tweak JIT runstack register sync for branches where it's not needed

svn: r15430
This commit is contained in:
Matthew Flatt 2009-07-11 04:08:34 +00:00
parent 2b5f12b6fa
commit 6cc6d84488

View File

@ -746,6 +746,9 @@ static void *top4;
# define mz_rs_sync_0() /* empty */ # define mz_rs_sync_0() /* empty */
#endif #endif
/* No need to sync if a branch just goes to an exception. */
# define mz_rs_sync_fail_branch() /* empty */
static void new_mapping(mz_jit_state *jitter) static void new_mapping(mz_jit_state *jitter)
{ {
jitter->num_mappings++; jitter->num_mappings++;
@ -1506,6 +1509,64 @@ static int is_short(Scheme_Object *obj, int fuel)
} }
#endif #endif
static int no_sync_change(Scheme_Object *obj, int fuel)
{
Scheme_Type t;
if (fuel <= 0)
return fuel;
t = SCHEME_TYPE(obj);
switch (t) {
case scheme_application2_type:
{
Scheme_App2_Rec *app = (Scheme_App2_Rec *)obj;
if (SCHEME_PRIMP(app->rator)
&& (SCHEME_PRIM_PROC_FLAGS(app->rator) & SCHEME_PRIM_IS_UNARY_INLINED)
&& (IS_NAMED_PRIM(app->rator, "car")
|| IS_NAMED_PRIM(app->rator, "cdr")
|| IS_NAMED_PRIM(app->rator, "cadr")
|| IS_NAMED_PRIM(app->rator, "cdar")
|| IS_NAMED_PRIM(app->rator, "caar")
|| IS_NAMED_PRIM(app->rator, "cddr"))) {
return no_sync_change(app->rand, fuel - 1);
}
return 0;
}
break;
case scheme_sequence_type:
{
Scheme_Sequence *seq = (Scheme_Sequence *)obj;
int i;
fuel -= seq->count;
for (i = seq->count; i--; ) {
fuel = no_sync_change(seq->array[i], fuel);
}
return fuel;
}
break;
case scheme_branch_type:
{
Scheme_Branch_Rec *branch = (Scheme_Branch_Rec *)obj;
fuel -= 3;
fuel = no_sync_change(branch->test, fuel);
fuel = no_sync_change(branch->tbranch, fuel);
return no_sync_change(branch->fbranch, fuel);
}
case scheme_toplevel_type:
case scheme_local_type:
case scheme_local_unbox_type:
return fuel - 1;
default:
if (t > _scheme_values_types_)
return fuel - 1;
else
return 0;
}
}
Scheme_Object *extract_global(Scheme_Object *o, Scheme_Native_Closure *nc) Scheme_Object *extract_global(Scheme_Object *o, Scheme_Native_Closure *nc)
{ {
/* GLOBAL ASSUMPTION: we assume that globals are the last thing /* GLOBAL ASSUMPTION: we assume that globals are the last thing
@ -3923,7 +3984,7 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
static int generate_inlined_constant_test(mz_jit_state *jitter, Scheme_App2_Rec *app, static int generate_inlined_constant_test(mz_jit_state *jitter, Scheme_App2_Rec *app,
Scheme_Object *cnst, Scheme_Object *cnst2, Scheme_Object *cnst, Scheme_Object *cnst2,
jit_insn **for_branch, int branch_short) jit_insn **for_branch, int branch_short, int need_sync)
/* de-sync'd ok */ /* de-sync'd ok */
{ {
GC_CAN_IGNORE jit_insn *ref, *ref2; GC_CAN_IGNORE jit_insn *ref, *ref2;
@ -3937,7 +3998,7 @@ static int generate_inlined_constant_test(mz_jit_state *jitter, Scheme_App2_Rec
mz_runstack_unskipped(jitter, 1); mz_runstack_unskipped(jitter, 1);
mz_rs_sync(); if (need_sync) mz_rs_sync();
__START_SHORT_JUMPS__(branch_short); __START_SHORT_JUMPS__(branch_short);
@ -3966,7 +4027,7 @@ static int generate_inlined_constant_test(mz_jit_state *jitter, Scheme_App2_Rec
static int generate_inlined_type_test(mz_jit_state *jitter, Scheme_App2_Rec *app, static int generate_inlined_type_test(mz_jit_state *jitter, Scheme_App2_Rec *app,
Scheme_Type lo_ty, Scheme_Type hi_ty, Scheme_Type lo_ty, Scheme_Type hi_ty,
jit_insn **for_branch, int branch_short) jit_insn **for_branch, int branch_short, int need_sync)
{ {
GC_CAN_IGNORE jit_insn *ref, *ref2, *ref3, *ref4; GC_CAN_IGNORE jit_insn *ref, *ref2, *ref3, *ref4;
int int_ok; int int_ok;
@ -3982,7 +4043,7 @@ static int generate_inlined_type_test(mz_jit_state *jitter, Scheme_App2_Rec *app
mz_runstack_unskipped(jitter, 1); mz_runstack_unskipped(jitter, 1);
mz_rs_sync(); if (need_sync) mz_rs_sync();
__START_SHORT_JUMPS__(branch_short); __START_SHORT_JUMPS__(branch_short);
@ -4086,7 +4147,7 @@ static int generate_vector_alloc(mz_jit_state *jitter, Scheme_Object *rator,
Scheme_App_Rec *app, Scheme_App2_Rec *app2, Scheme_App3_Rec *app3); Scheme_App_Rec *app, Scheme_App2_Rec *app2, Scheme_App3_Rec *app3);
static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, int is_tail, int multi_ok, static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, int is_tail, int multi_ok,
jit_insn **for_branch, int branch_short) jit_insn **for_branch, int branch_short, int need_sync)
/* de-sync's, unless branch */ /* de-sync's, unless branch */
{ {
Scheme_Object *rator = app->rator; Scheme_Object *rator = app->rator;
@ -4114,61 +4175,61 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in
scheme_direct_call_count++; scheme_direct_call_count++;
if (IS_NAMED_PRIM(rator, "not")) { if (IS_NAMED_PRIM(rator, "not")) {
generate_inlined_constant_test(jitter, app, scheme_false, NULL, for_branch, branch_short); generate_inlined_constant_test(jitter, app, scheme_false, NULL, for_branch, branch_short, need_sync);
return 1; return 1;
} else if (IS_NAMED_PRIM(rator, "null?")) { } else if (IS_NAMED_PRIM(rator, "null?")) {
generate_inlined_constant_test(jitter, app, scheme_null, NULL, for_branch, branch_short); generate_inlined_constant_test(jitter, app, scheme_null, NULL, for_branch, branch_short, need_sync);
return 1; return 1;
} else if (IS_NAMED_PRIM(rator, "pair?")) { } else if (IS_NAMED_PRIM(rator, "pair?")) {
generate_inlined_type_test(jitter, app, scheme_pair_type, scheme_pair_type, for_branch, branch_short); generate_inlined_type_test(jitter, app, scheme_pair_type, scheme_pair_type, for_branch, branch_short, need_sync);
return 1; return 1;
} else if (IS_NAMED_PRIM(rator, "mpair?")) { } else if (IS_NAMED_PRIM(rator, "mpair?")) {
generate_inlined_type_test(jitter, app, scheme_mutable_pair_type, scheme_mutable_pair_type, for_branch, branch_short); generate_inlined_type_test(jitter, app, scheme_mutable_pair_type, scheme_mutable_pair_type, for_branch, branch_short, need_sync);
return 1; return 1;
} else if (IS_NAMED_PRIM(rator, "symbol?")) { } else if (IS_NAMED_PRIM(rator, "symbol?")) {
generate_inlined_type_test(jitter, app, scheme_symbol_type, scheme_symbol_type, for_branch, branch_short); generate_inlined_type_test(jitter, app, scheme_symbol_type, scheme_symbol_type, for_branch, branch_short, need_sync);
return 1; return 1;
} else if (IS_NAMED_PRIM(rator, "syntax?")) { } else if (IS_NAMED_PRIM(rator, "syntax?")) {
generate_inlined_type_test(jitter, app, scheme_stx_type, scheme_stx_type, for_branch, branch_short); generate_inlined_type_test(jitter, app, scheme_stx_type, scheme_stx_type, for_branch, branch_short, need_sync);
return 1; return 1;
} else if (IS_NAMED_PRIM(rator, "char?")) { } else if (IS_NAMED_PRIM(rator, "char?")) {
generate_inlined_type_test(jitter, app, scheme_char_type, scheme_char_type, for_branch, branch_short); generate_inlined_type_test(jitter, app, scheme_char_type, scheme_char_type, for_branch, branch_short, need_sync);
return 1; return 1;
} else if (IS_NAMED_PRIM(rator, "boolean?")) { } else if (IS_NAMED_PRIM(rator, "boolean?")) {
generate_inlined_constant_test(jitter, app, scheme_false, scheme_true, for_branch, branch_short); generate_inlined_constant_test(jitter, app, scheme_false, scheme_true, for_branch, branch_short, need_sync);
return 1; return 1;
} else if (IS_NAMED_PRIM(rator, "number?")) { } else if (IS_NAMED_PRIM(rator, "number?")) {
generate_inlined_type_test(jitter, app, scheme_integer_type, scheme_complex_type, for_branch, branch_short); generate_inlined_type_test(jitter, app, scheme_integer_type, scheme_complex_type, for_branch, branch_short, need_sync);
return 1; return 1;
} else if (IS_NAMED_PRIM(rator, "real?")) { } else if (IS_NAMED_PRIM(rator, "real?")) {
generate_inlined_type_test(jitter, app, scheme_integer_type, scheme_double_type, for_branch, branch_short); generate_inlined_type_test(jitter, app, scheme_integer_type, scheme_double_type, for_branch, branch_short, need_sync);
return 1; return 1;
} else if (IS_NAMED_PRIM(rator, "exact-integer?")) { } else if (IS_NAMED_PRIM(rator, "exact-integer?")) {
generate_inlined_type_test(jitter, app, scheme_integer_type, scheme_bignum_type, for_branch, branch_short); generate_inlined_type_test(jitter, app, scheme_integer_type, scheme_bignum_type, for_branch, branch_short, need_sync);
return 1; return 1;
} else if (IS_NAMED_PRIM(rator, "fixnum?")) { } else if (IS_NAMED_PRIM(rator, "fixnum?")) {
generate_inlined_type_test(jitter, app, scheme_integer_type, scheme_integer_type, for_branch, branch_short); generate_inlined_type_test(jitter, app, scheme_integer_type, scheme_integer_type, for_branch, branch_short, need_sync);
return 1; return 1;
} else if (IS_NAMED_PRIM(rator, "inexact-real?")) { } else if (IS_NAMED_PRIM(rator, "inexact-real?")) {
generate_inlined_type_test(jitter, app, SCHEME_FLOAT_TYPE, scheme_double_type, for_branch, branch_short); generate_inlined_type_test(jitter, app, SCHEME_FLOAT_TYPE, scheme_double_type, for_branch, branch_short, need_sync);
return 1; return 1;
} else if (IS_NAMED_PRIM(rator, "procedure?")) { } else if (IS_NAMED_PRIM(rator, "procedure?")) {
generate_inlined_type_test(jitter, app, scheme_prim_type, scheme_native_closure_type, for_branch, branch_short); generate_inlined_type_test(jitter, app, scheme_prim_type, scheme_native_closure_type, for_branch, branch_short, need_sync);
return 1; return 1;
} else if (IS_NAMED_PRIM(rator, "vector?")) { } else if (IS_NAMED_PRIM(rator, "vector?")) {
generate_inlined_type_test(jitter, app, scheme_vector_type, scheme_vector_type, for_branch, branch_short); generate_inlined_type_test(jitter, app, scheme_vector_type, scheme_vector_type, for_branch, branch_short, need_sync);
return 1; return 1;
} else if (IS_NAMED_PRIM(rator, "box?")) { } else if (IS_NAMED_PRIM(rator, "box?")) {
generate_inlined_type_test(jitter, app, scheme_box_type, scheme_box_type, for_branch, branch_short); generate_inlined_type_test(jitter, app, scheme_box_type, scheme_box_type, for_branch, branch_short, need_sync);
return 1; return 1;
} else if (IS_NAMED_PRIM(rator, "string?")) { } else if (IS_NAMED_PRIM(rator, "string?")) {
generate_inlined_type_test(jitter, app, scheme_char_string_type, scheme_char_string_type, for_branch, branch_short); generate_inlined_type_test(jitter, app, scheme_char_string_type, scheme_char_string_type, for_branch, branch_short, need_sync);
return 1; return 1;
} else if (IS_NAMED_PRIM(rator, "bytes?")) { } else if (IS_NAMED_PRIM(rator, "bytes?")) {
generate_inlined_type_test(jitter, app, scheme_byte_string_type, scheme_byte_string_type, for_branch, branch_short); generate_inlined_type_test(jitter, app, scheme_byte_string_type, scheme_byte_string_type, for_branch, branch_short, need_sync);
return 1; return 1;
} else if (IS_NAMED_PRIM(rator, "eof-object?")) { } else if (IS_NAMED_PRIM(rator, "eof-object?")) {
generate_inlined_constant_test(jitter, app, scheme_eof, NULL, for_branch, branch_short); generate_inlined_constant_test(jitter, app, scheme_eof, NULL, for_branch, branch_short, need_sync);
return 1; return 1;
} else if (IS_NAMED_PRIM(rator, "zero?")) { } else if (IS_NAMED_PRIM(rator, "zero?")) {
generate_arith(jitter, rator, app->rand, NULL, 1, 0, 0, 0, for_branch, branch_short); generate_arith(jitter, rator, app->rand, NULL, 1, 0, 0, 0, for_branch, branch_short);
@ -4192,7 +4253,7 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in
mz_runstack_unskipped(jitter, 1); mz_runstack_unskipped(jitter, 1);
mz_rs_sync(); if (need_sync) mz_rs_sync();
/* Jump ahead if it's a fixnum: */ /* Jump ahead if it's a fixnum: */
__START_TINY_JUMPS__(1); __START_TINY_JUMPS__(1);
@ -4265,7 +4326,7 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in
mz_runstack_unskipped(jitter, 1); mz_runstack_unskipped(jitter, 1);
mz_rs_sync(); mz_rs_sync_fail_branch();
__START_TINY_JUMPS__(1); __START_TINY_JUMPS__(1);
@ -4334,7 +4395,7 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in
mz_runstack_unskipped(jitter, 1); mz_runstack_unskipped(jitter, 1);
mz_rs_sync(); mz_rs_sync_fail_branch();
__START_TINY_JUMPS__(1); __START_TINY_JUMPS__(1);
@ -4372,7 +4433,7 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in
mz_runstack_unskipped(jitter, 1); mz_runstack_unskipped(jitter, 1);
mz_rs_sync(); mz_rs_sync_fail_branch();
__START_TINY_JUMPS__(1); __START_TINY_JUMPS__(1);
ref = jit_bmci_ul(jit_forward(), JIT_R0, 0x1); ref = jit_bmci_ul(jit_forward(), JIT_R0, 0x1);
@ -4404,7 +4465,7 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in
mz_runstack_unskipped(jitter, 1); mz_runstack_unskipped(jitter, 1);
mz_rs_sync(); mz_rs_sync_fail_branch();
__START_TINY_JUMPS__(1); __START_TINY_JUMPS__(1);
ref = jit_bmci_ul(jit_forward(), JIT_R0, 0x1); ref = jit_bmci_ul(jit_forward(), JIT_R0, 0x1);
@ -4731,7 +4792,7 @@ static int generate_vector_op(mz_jit_state *jitter, int set, int int_ready)
} }
static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, int is_tail, int multi_ok, static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, int is_tail, int multi_ok,
jit_insn **for_branch, int branch_short) jit_insn **for_branch, int branch_short, int need_sync)
/* de-sync's; for branch, sync'd before */ /* de-sync's; for branch, sync'd before */
{ {
Scheme_Object *rator = app->rator; Scheme_Object *rator = app->rator;
@ -4774,7 +4835,7 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i
generate_non_tail(a2, jitter, 0, 1); generate_non_tail(a2, jitter, 0, 1);
CHECK_LIMIT(); CHECK_LIMIT();
mz_rs_sync(); if (need_sync) mz_rs_sync();
mz_runstack_unskipped(jitter, 2); mz_runstack_unskipped(jitter, 2);
@ -4812,7 +4873,7 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i
generate_two_args(a2, a1, jitter, 0, 2); generate_two_args(a2, a1, jitter, 0, 2);
CHECK_LIMIT(); CHECK_LIMIT();
mz_rs_sync(); if (need_sync) mz_rs_sync();
__START_SHORT_JUMPS__(branch_short); __START_SHORT_JUMPS__(branch_short);
@ -4958,7 +5019,7 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i
generate_two_args(app->rand1, app->rand2, jitter, 1, 2); generate_two_args(app->rand1, app->rand2, jitter, 1, 2);
CHECK_LIMIT(); CHECK_LIMIT();
mz_rs_sync(); mz_rs_sync_fail_branch();
__START_TINY_JUMPS__(1); __START_TINY_JUMPS__(1);
ref = jit_bmci_ul(jit_forward(), JIT_R0, 0x1); ref = jit_bmci_ul(jit_forward(), JIT_R0, 0x1);
@ -5374,14 +5435,14 @@ static int generate_vector_alloc(mz_jit_state *jitter, Scheme_Object *rator,
return 1; return 1;
} }
int generate_inlined_test(mz_jit_state *jitter, Scheme_Object *obj, int branch_short, jit_insn **refs) int generate_inlined_test(mz_jit_state *jitter, Scheme_Object *obj, int branch_short, jit_insn **refs, int need_sync)
/* de-sync'd ok; syncs before jump */ /* de-sync'd ok; syncs before jump */
{ {
switch (SCHEME_TYPE(obj)) { switch (SCHEME_TYPE(obj)) {
case scheme_application2_type: case scheme_application2_type:
return generate_inlined_unary(jitter, (Scheme_App2_Rec *)obj, 0, 0, refs, branch_short); return generate_inlined_unary(jitter, (Scheme_App2_Rec *)obj, 0, 0, refs, branch_short, need_sync);
case scheme_application3_type: case scheme_application3_type:
return generate_inlined_binary(jitter, (Scheme_App3_Rec *)obj, 0, 0, refs, branch_short); return generate_inlined_binary(jitter, (Scheme_App3_Rec *)obj, 0, 0, refs, branch_short, need_sync);
} }
return 0; return 0;
@ -5770,7 +5831,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
/* Other parts of the JIT rely on this code not modifying R1 */ /* Other parts of the JIT rely on this code not modifying R1 */
START_JIT_DATA(); START_JIT_DATA();
LOG_IT(("top-level\n")); LOG_IT(("top-level\n"));
mz_rs_sync(); mz_rs_sync_fail_branch();
/* Load global array: */ /* Load global array: */
pos = mz_remap(SCHEME_TOPLEVEL_DEPTH(obj)); pos = mz_remap(SCHEME_TOPLEVEL_DEPTH(obj));
mz_rs_ldxi(JIT_R2, pos); mz_rs_ldxi(JIT_R2, pos);
@ -5828,7 +5889,6 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
case scheme_syntax_type: case scheme_syntax_type:
{ {
int pos; int pos;
mz_rs_sync();
pos = SCHEME_PINT_VAL(obj); pos = SCHEME_PINT_VAL(obj);
switch (pos) { switch (pos) {
case CASE_LAMBDA_EXPD: case CASE_LAMBDA_EXPD:
@ -5855,7 +5915,6 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
evaluation, allow multiple values. */ evaluation, allow multiple values. */
generate_non_tail(seq->array[0], jitter, 1, 1); generate_non_tail(seq->array[0], jitter, 1, 1);
CHECK_LIMIT(); CHECK_LIMIT();
mz_rs_sync();
/* Save value(s) */ /* Save value(s) */
jit_movr_p(JIT_V1, JIT_R0); jit_movr_p(JIT_V1, JIT_R0);
@ -5975,10 +6034,10 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
generate_non_tail(v, jitter, 0, 1); generate_non_tail(v, jitter, 0, 1);
CHECK_LIMIT(); CHECK_LIMIT();
mz_rs_sync();
/* If v is not known to produce a procedure, then check result: */ /* If v is not known to produce a procedure, then check result: */
if (!is_a_procedure(v, jitter)) { if (!is_a_procedure(v, jitter)) {
mz_rs_sync();
(void)jit_bmsi_l(bad_app_vals_target, JIT_R0, 0x1); (void)jit_bmsi_l(bad_app_vals_target, JIT_R0, 0x1);
jit_ldxi_s(JIT_R1, JIT_R0, &((Scheme_Object *)0x0)->type); jit_ldxi_s(JIT_R1, JIT_R0, &((Scheme_Object *)0x0)->type);
(void)jit_blti_i(bad_app_vals_target, JIT_R1, scheme_prim_type); (void)jit_blti_i(bad_app_vals_target, JIT_R1, scheme_prim_type);
@ -6107,6 +6166,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
LOG_IT(("boxenv\n")); LOG_IT(("boxenv\n"));
mz_rs_sync();
JIT_UPDATE_THREAD_RSPTR_IF_NEEDED(); JIT_UPDATE_THREAD_RSPTR_IF_NEEDED();
p = (Scheme_Object *)SCHEME_IPTR_VAL(obj); p = (Scheme_Object *)SCHEME_IPTR_VAL(obj);
@ -6129,6 +6189,8 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
break; break;
case REF_EXPD: case REF_EXPD:
{ {
mz_rs_sync();
obj = SCHEME_IPTR_VAL(obj); obj = SCHEME_IPTR_VAL(obj);
/* Load global array: */ /* Load global array: */
@ -6154,6 +6216,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
break; break;
default: default:
{ {
mz_rs_sync();
JIT_UPDATE_THREAD_RSPTR_IF_NEEDED(); JIT_UPDATE_THREAD_RSPTR_IF_NEEDED();
obj = SCHEME_IPTR_VAL(obj); obj = SCHEME_IPTR_VAL(obj);
(void)jit_patchable_movi_p(JIT_R2, obj); /* !! */ (void)jit_patchable_movi_p(JIT_R2, obj); /* !! */
@ -6197,7 +6260,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
Scheme_Object *args[2]; Scheme_Object *args[2];
int r; int r;
r = generate_inlined_unary(jitter, app, is_tail, multi_ok, NULL, 1); r = generate_inlined_unary(jitter, app, is_tail, multi_ok, NULL, 1, 0);
CHECK_LIMIT(); CHECK_LIMIT();
if (r) { if (r) {
if (target != JIT_R0) if (target != JIT_R0)
@ -6224,7 +6287,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
Scheme_Object *args[3]; Scheme_Object *args[3];
int r; int r;
r = generate_inlined_binary(jitter, app, is_tail, multi_ok, NULL, 1); r = generate_inlined_binary(jitter, app, is_tail, multi_ok, NULL, 1, 0);
CHECK_LIMIT(); CHECK_LIMIT();
if (r) { if (r) {
if (target != JIT_R0) if (target != JIT_R0)
@ -6267,7 +6330,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
{ {
Scheme_Branch_Rec *branch = (Scheme_Branch_Rec *)obj; Scheme_Branch_Rec *branch = (Scheme_Branch_Rec *)obj;
jit_insn *refs[6], *ref2; jit_insn *refs[6], *ref2;
int nsrs, nsrs1, g1, g2, amt; int nsrs, nsrs1, g1, g2, amt, need_sync;
#ifdef NEED_LONG_JUMPS #ifdef NEED_LONG_JUMPS
int then_short_ok, else_short_ok; int then_short_ok, else_short_ok;
#else #else
@ -6294,10 +6357,17 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
refs[4] = NULL; refs[4] = NULL;
refs[5] = NULL; /* a jmpi instead of a test branch */ refs[5] = NULL; /* a jmpi instead of a test branch */
if (!generate_inlined_test(jitter, branch->test, then_short_ok, refs)) { /* Avoid rs_sync if neither branch changes the sync state. */
if ((no_sync_change(branch->tbranch, 32) > 0)
&& (no_sync_change(branch->fbranch, 32) > 0))
need_sync = 0;
else
need_sync = 1;
if (!generate_inlined_test(jitter, branch->test, then_short_ok, refs, need_sync)) {
CHECK_LIMIT(); CHECK_LIMIT();
generate_non_tail(branch->test, jitter, 0, 1); generate_non_tail(branch->test, jitter, 0, 1);
mz_rs_sync(); if (need_sync) mz_rs_sync();
CHECK_LIMIT(); CHECK_LIMIT();
__START_SHORT_JUMPS__(then_short_ok); __START_SHORT_JUMPS__(then_short_ok);
refs[0] = jit_beqi_p(jit_forward(), JIT_R0, scheme_false); refs[0] = jit_beqi_p(jit_forward(), JIT_R0, scheme_false);
@ -6319,7 +6389,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
if (!is_tail) { if (!is_tail) {
if (amt) if (amt)
mz_rs_inc(amt); mz_rs_inc(amt);
mz_rs_sync(); if (need_sync) mz_rs_sync();
} }
__START_SHORT_JUMPS__(else_short_ok); __START_SHORT_JUMPS__(else_short_ok);
ref2 = jit_jmpi(jit_forward()); ref2 = jit_jmpi(jit_forward());
@ -6330,7 +6400,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
nsrs1 = 0; nsrs1 = 0;
} }
jitter->need_set_rs = nsrs; jitter->need_set_rs = nsrs;
mz_rs_sync_0(); if (need_sync) mz_rs_sync_0();
/* False branch */ /* False branch */
mz_runstack_saved(jitter); mz_runstack_saved(jitter);
@ -6366,7 +6436,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
if (!is_tail) { if (!is_tail) {
if (amt) if (amt)
mz_rs_inc(amt); mz_rs_inc(amt);
mz_rs_sync(); if (need_sync) mz_rs_sync();
} }
} else { } else {
jitter->need_set_rs = 0; jitter->need_set_rs = 0;