JIT tweaks

svn: r17102
This commit is contained in:
Matthew Flatt 2009-11-30 02:52:43 +00:00
parent 06288a8b7f
commit 06f231a0a7

View File

@ -207,7 +207,7 @@ typedef Scheme_Object *(*Native_Get_Arity_Proc)(Scheme_Object *o, int dumm1, int
static Native_Check_Arity_Proc check_arity_code; static Native_Check_Arity_Proc check_arity_code;
static Native_Get_Arity_Proc get_arity_code; static Native_Get_Arity_Proc get_arity_code;
static int generate_non_tail(Scheme_Object *obj, mz_jit_state *jitter, int multi_ok, int need_ends); static int generate_non_tail(Scheme_Object *obj, mz_jit_state *jitter, int multi_ok, int need_ends, int ignored);
static int generate(Scheme_Object *obj, mz_jit_state *jitter, int tail_ok, int multi_ok, int target); static int generate(Scheme_Object *obj, mz_jit_state *jitter, int tail_ok, int multi_ok, int target);
static void *generate_lambda_simple_arity_check(int num_params, int has_rest, int is_method, int permanent); static void *generate_lambda_simple_arity_check(int num_params, int has_rest, int is_method, int permanent);
static void generate_case_lambda(Scheme_Case_Lambda *c, Scheme_Native_Closure_Data *ndata, static void generate_case_lambda(Scheme_Case_Lambda *c, Scheme_Native_Closure_Data *ndata,
@ -2098,17 +2098,25 @@ static int is_constant_and_avoids_r1(Scheme_Object *obj)
return (t >= _scheme_compiled_values_types_); return (t >= _scheme_compiled_values_types_);
} }
static int avoids_r1(Scheme_Object *obj) static int is_relatively_constant_and_avoids_r1(Scheme_Object *obj, Scheme_Object *wrt)
{ {
Scheme_Type t = SCHEME_TYPE(obj); Scheme_Type t;
if (SAME_TYPE(t, scheme_toplevel_type)) { if (is_constant_and_avoids_r1(obj))
return 1; return 1;
} else if (SAME_TYPE(t, scheme_local_type)
|| SAME_TYPE(t, scheme_local_unbox_type)) { t = SCHEME_TYPE(obj);
return 1; if (SAME_TYPE(t, scheme_local_type)) {
} else /* Must have clearing or other-clears flag set */
return is_constant_and_avoids_r1(obj); Scheme_Type t2 = SCHEME_TYPE(wrt);
if (t2 == scheme_local_type) {
/* If different local vars, then order doesn't matter */
if (SCHEME_LOCAL_POS(wrt) != SCHEME_LOCAL_POS(obj))
return 1;
}
}
return 0;
} }
/*========================================================================*/ /*========================================================================*/
@ -3396,7 +3404,7 @@ static int generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_
need_safety = 0; need_safety = 0;
} }
generate_non_tail(rator, jitter, 0, !need_non_tail); /* sync'd after args below */ generate_non_tail(rator, jitter, 0, !need_non_tail, 0); /* sync'd after args below */
CHECK_LIMIT(); CHECK_LIMIT();
if (num_rands) { if (num_rands) {
@ -3432,7 +3440,7 @@ static int generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_
CHECK_LIMIT(); CHECK_LIMIT();
need_safety = 0; need_safety = 0;
} }
generate_non_tail(arg, jitter, 0, !need_non_tail); /* sync'd below */ generate_non_tail(arg, jitter, 0, !need_non_tail, 0); /* sync'd below */
RESUME_JIT_DATA(); RESUME_JIT_DATA();
CHECK_LIMIT(); CHECK_LIMIT();
if ((i == num_rands - 1) && !direct_prim && !reorder_ok && !direct_self && !proc_already_in_place) { if ((i == num_rands - 1) && !direct_prim && !reorder_ok && !direct_self && !proc_already_in_place) {
@ -4163,7 +4171,7 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
if (rand2 && !simple_rand && !simple_rand2) { if (rand2 && !simple_rand && !simple_rand2) {
mz_runstack_skipped(jitter, 1); mz_runstack_skipped(jitter, 1);
generate_non_tail(rand, jitter, 0, 1); /* sync'd later */ generate_non_tail(rand, jitter, 0, 1, 0); /* sync'd later */
CHECK_LIMIT(); CHECK_LIMIT();
mz_runstack_unskipped(jitter, 1); mz_runstack_unskipped(jitter, 1);
mz_rs_dec(1); mz_rs_dec(1);
@ -4177,14 +4185,14 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
if (SAME_TYPE(SCHEME_TYPE(rand), scheme_local_type)) if (SAME_TYPE(SCHEME_TYPE(rand), scheme_local_type))
generate(rand, jitter, 0, 0, JIT_R1); /* sync'd below */ generate(rand, jitter, 0, 0, JIT_R1); /* sync'd below */
else { else {
generate_non_tail(rand, jitter, 0, 1); /* sync'd below */ generate_non_tail(rand, jitter, 0, 1, 0); /* sync'd below */
CHECK_LIMIT(); CHECK_LIMIT();
jit_movr_p(JIT_R1, JIT_R0); jit_movr_p(JIT_R1, JIT_R0);
} }
CHECK_LIMIT(); CHECK_LIMIT();
generate(rand2, jitter, 0, 0, JIT_R0); /* sync'd below */ generate(rand2, jitter, 0, 0, JIT_R0); /* sync'd below */
} else { } else {
generate_non_tail(rand2 ? rand2 : rand, jitter, 0, 1); /* sync'd below */ generate_non_tail(rand2 ? rand2 : rand, jitter, 0, 1, 0); /* sync'd below */
} }
CHECK_LIMIT(); CHECK_LIMIT();
/* sync'd in three branches below */ /* sync'd in three branches below */
@ -4369,10 +4377,11 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
if (arith == 1) { if (arith == 1) {
jit_andi_ul(JIT_R2, JIT_R1, (~0x1)); jit_andi_ul(JIT_R2, JIT_R1, (~0x1));
if (unsafe_fx && !overflow_refslow) if (unsafe_fx && !overflow_refslow)
jit_addr_l(JIT_R2, JIT_R2, JIT_R0); jit_addr_l(JIT_R0, JIT_R2, JIT_R0);
else else {
(void)jit_boaddr_l(refslow, JIT_R2, JIT_R0); (void)jit_boaddr_l(refslow, JIT_R2, JIT_R0);
jit_movr_p(JIT_R0, JIT_R2); jit_movr_p(JIT_R0, JIT_R2);
}
} else if (arith == -1) { } else if (arith == -1) {
if (reversed) { if (reversed) {
jit_movr_p(JIT_R2, JIT_R0); jit_movr_p(JIT_R2, JIT_R0);
@ -4521,12 +4530,13 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
} else { } else {
/* Non-constant arg is in JIT_R0 */ /* Non-constant arg is in JIT_R0 */
if (arith == 1) { if (arith == 1) {
jit_movr_p(JIT_R2, JIT_R0);
if (unsafe_fx && !overflow_refslow) if (unsafe_fx && !overflow_refslow)
jit_addi_l(JIT_R2, JIT_R2, v << 1); jit_addi_l(JIT_R0, JIT_R0, v << 1);
else else {
jit_movr_p(JIT_R2, JIT_R0);
(void)jit_boaddi_l(refslow, JIT_R2, v << 1); (void)jit_boaddi_l(refslow, JIT_R2, v << 1);
jit_movr_p(JIT_R0, JIT_R2); jit_movr_p(JIT_R0, JIT_R2);
}
} else if (arith == -1) { } else if (arith == -1) {
if (reversed) { if (reversed) {
(void)jit_movi_p(JIT_R2, scheme_make_integer(v)); (void)jit_movi_p(JIT_R2, scheme_make_integer(v));
@ -4536,12 +4546,13 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
(void)jit_bosubr_l(refslow, JIT_R2, JIT_R0); (void)jit_bosubr_l(refslow, JIT_R2, JIT_R0);
jit_addi_ul(JIT_R0, JIT_R2, 0x1); jit_addi_ul(JIT_R0, JIT_R2, 0x1);
} else { } else {
jit_movr_p(JIT_R2, JIT_R0);
if (unsafe_fx && !overflow_refslow) if (unsafe_fx && !overflow_refslow)
jit_subi_l(JIT_R2, JIT_R2, v << 1); jit_subi_l(JIT_R0, JIT_R0, v << 1);
else else {
jit_movr_p(JIT_R2, JIT_R0);
(void)jit_bosubi_l(refslow, JIT_R2, v << 1); (void)jit_bosubi_l(refslow, JIT_R2, v << 1);
jit_movr_p(JIT_R0, JIT_R2); jit_movr_p(JIT_R0, JIT_R2);
}
} }
} else if (arith == 2) { } else if (arith == 2) {
if (v == 1) { if (v == 1) {
@ -5047,7 +5058,7 @@ static int generate_inlined_constant_test(mz_jit_state *jitter, Scheme_App2_Rec
mz_runstack_skipped(jitter, 1); mz_runstack_skipped(jitter, 1);
generate_non_tail(app->rand, jitter, 0, 1); generate_non_tail(app->rand, jitter, 0, 1, 0);
CHECK_LIMIT(); CHECK_LIMIT();
mz_runstack_unskipped(jitter, 1); mz_runstack_unskipped(jitter, 1);
@ -5092,7 +5103,7 @@ static int generate_inlined_type_test(mz_jit_state *jitter, Scheme_App2_Rec *app
mz_runstack_skipped(jitter, 1); mz_runstack_skipped(jitter, 1);
generate_non_tail(app->rand, jitter, 0, 1); generate_non_tail(app->rand, jitter, 0, 1, 0);
CHECK_LIMIT(); CHECK_LIMIT();
mz_runstack_unskipped(jitter, 1); mz_runstack_unskipped(jitter, 1);
@ -5302,7 +5313,7 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in
mz_runstack_skipped(jitter, 1); mz_runstack_skipped(jitter, 1);
generate_non_tail(app->rand, jitter, 0, 1); generate_non_tail(app->rand, jitter, 0, 1, 0);
CHECK_LIMIT(); CHECK_LIMIT();
mz_runstack_unskipped(jitter, 1); mz_runstack_unskipped(jitter, 1);
@ -5375,7 +5386,7 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in
mz_runstack_skipped(jitter, 1); mz_runstack_skipped(jitter, 1);
generate_non_tail(app->rand, jitter, 0, 1); generate_non_tail(app->rand, jitter, 0, 1, 0);
CHECK_LIMIT(); CHECK_LIMIT();
mz_runstack_unskipped(jitter, 1); mz_runstack_unskipped(jitter, 1);
@ -5444,7 +5455,7 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in
mz_runstack_skipped(jitter, 1); mz_runstack_skipped(jitter, 1);
generate_non_tail(app->rand, jitter, 0, 1); generate_non_tail(app->rand, jitter, 0, 1, 0);
CHECK_LIMIT(); CHECK_LIMIT();
mz_runstack_unskipped(jitter, 1); mz_runstack_unskipped(jitter, 1);
@ -5485,7 +5496,7 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in
mz_runstack_skipped(jitter, 1); mz_runstack_skipped(jitter, 1);
generate_non_tail(app->rand, jitter, 0, 1); generate_non_tail(app->rand, jitter, 0, 1, 0);
CHECK_LIMIT(); CHECK_LIMIT();
mz_runstack_unskipped(jitter, 1); mz_runstack_unskipped(jitter, 1);
@ -5506,7 +5517,7 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in
mz_runstack_skipped(jitter, 1); mz_runstack_skipped(jitter, 1);
generate_non_tail(app->rand, jitter, 0, 1); generate_non_tail(app->rand, jitter, 0, 1, 0);
CHECK_LIMIT(); CHECK_LIMIT();
mz_runstack_unskipped(jitter, 1); mz_runstack_unskipped(jitter, 1);
@ -5539,7 +5550,7 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in
mz_runstack_skipped(jitter, 1); mz_runstack_skipped(jitter, 1);
generate_non_tail(app->rand, jitter, 0, 1); generate_non_tail(app->rand, jitter, 0, 1, 0);
CHECK_LIMIT(); CHECK_LIMIT();
mz_runstack_unskipped(jitter, 1); mz_runstack_unskipped(jitter, 1);
@ -5559,7 +5570,7 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in
mz_runstack_skipped(jitter, 1); mz_runstack_skipped(jitter, 1);
generate_non_tail(app->rand, jitter, 0, 1); generate_non_tail(app->rand, jitter, 0, 1, 0);
CHECK_LIMIT(); CHECK_LIMIT();
mz_runstack_unskipped(jitter, 1); mz_runstack_unskipped(jitter, 1);
@ -5587,7 +5598,7 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in
mz_runstack_skipped(jitter, 1); mz_runstack_skipped(jitter, 1);
generate_non_tail(app->rand, jitter, 0, 1); generate_non_tail(app->rand, jitter, 0, 1, 0);
CHECK_LIMIT(); CHECK_LIMIT();
mz_runstack_unskipped(jitter, 1); mz_runstack_unskipped(jitter, 1);
@ -5600,7 +5611,7 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in
mz_runstack_skipped(jitter, 1); mz_runstack_skipped(jitter, 1);
generate_non_tail(app->rand, jitter, 0, 1); generate_non_tail(app->rand, jitter, 0, 1, 0);
CHECK_LIMIT(); CHECK_LIMIT();
mz_runstack_unskipped(jitter, 1); mz_runstack_unskipped(jitter, 1);
@ -5646,13 +5657,13 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in
} else if (IS_NAMED_PRIM(rator, "list*")) { } else if (IS_NAMED_PRIM(rator, "list*")) {
/* on a single argument, `list*' is identity */ /* on a single argument, `list*' is identity */
mz_runstack_skipped(jitter, 1); mz_runstack_skipped(jitter, 1);
generate_non_tail(app->rand, jitter, 0, 1); generate_non_tail(app->rand, jitter, 0, 1, 0);
CHECK_LIMIT(); CHECK_LIMIT();
mz_runstack_unskipped(jitter, 1); mz_runstack_unskipped(jitter, 1);
return 1; return 1;
} else if (IS_NAMED_PRIM(rator, "list")) { } else if (IS_NAMED_PRIM(rator, "list")) {
mz_runstack_skipped(jitter, 1); mz_runstack_skipped(jitter, 1);
generate_non_tail(app->rand, jitter, 0, 1); generate_non_tail(app->rand, jitter, 0, 1, 0);
CHECK_LIMIT(); CHECK_LIMIT();
mz_rs_sync(); mz_rs_sync();
mz_runstack_unskipped(jitter, 1); mz_runstack_unskipped(jitter, 1);
@ -5660,7 +5671,7 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in
return generate_cons_alloc(jitter, 0, 0); return generate_cons_alloc(jitter, 0, 0);
} else if (IS_NAMED_PRIM(rator, "box")) { } else if (IS_NAMED_PRIM(rator, "box")) {
mz_runstack_skipped(jitter, 1); mz_runstack_skipped(jitter, 1);
generate_non_tail(app->rand, jitter, 0, 1); generate_non_tail(app->rand, jitter, 0, 1, 0);
CHECK_LIMIT(); CHECK_LIMIT();
mz_runstack_unskipped(jitter, 1); mz_runstack_unskipped(jitter, 1);
mz_rs_sync(); mz_rs_sync();
@ -5704,14 +5715,14 @@ static int generate_two_args(Scheme_Object *rand1, Scheme_Object *rand2, mz_jit_
{ {
int simple1, simple2, direction = 1; int simple1, simple2, direction = 1;
simple1 = is_constant_and_avoids_r1(rand1); simple1 = is_relatively_constant_and_avoids_r1(rand1, rand2);
simple2 = is_constant_and_avoids_r1(rand2); simple2 = is_relatively_constant_and_avoids_r1(rand2, rand1);
if (!simple1) { if (!simple1) {
if (simple2) { if (simple2) {
mz_runstack_skipped(jitter, skipped); mz_runstack_skipped(jitter, skipped);
generate_non_tail(rand1, jitter, 0, 1); /* no sync... */ generate_non_tail(rand1, jitter, 0, 1, 0); /* no sync... */
CHECK_LIMIT(); CHECK_LIMIT();
jit_movr_p(JIT_R1, JIT_R0); jit_movr_p(JIT_R1, JIT_R0);
@ -5729,7 +5740,7 @@ static int generate_two_args(Scheme_Object *rand1, Scheme_Object *rand2, mz_jit_
mz_runstack_unskipped(jitter, skipped); mz_runstack_unskipped(jitter, skipped);
} else { } else {
mz_runstack_skipped(jitter, skipped); mz_runstack_skipped(jitter, skipped);
generate_non_tail(rand1, jitter, 0, 1); /* no sync... */ generate_non_tail(rand1, jitter, 0, 1, 0); /* no sync... */
CHECK_LIMIT(); CHECK_LIMIT();
mz_runstack_unskipped(jitter, skipped); mz_runstack_unskipped(jitter, skipped);
@ -5739,7 +5750,7 @@ static int generate_two_args(Scheme_Object *rand1, Scheme_Object *rand2, mz_jit_
mz_rs_str(JIT_R0); mz_rs_str(JIT_R0);
mz_runstack_skipped(jitter, skipped-1); mz_runstack_skipped(jitter, skipped-1);
generate_non_tail(rand2, jitter, 0, 1); /* no sync... */ generate_non_tail(rand2, jitter, 0, 1, 0); /* no sync... */
CHECK_LIMIT(); CHECK_LIMIT();
jit_movr_p(JIT_R1, JIT_R0); jit_movr_p(JIT_R1, JIT_R0);
@ -5756,7 +5767,7 @@ static int generate_two_args(Scheme_Object *rand1, Scheme_Object *rand2, mz_jit_
generate(rand2, jitter, 0, 0, JIT_R1); /* no sync... */ generate(rand2, jitter, 0, 0, JIT_R1); /* no sync... */
CHECK_LIMIT(); CHECK_LIMIT();
} else { } else {
generate_non_tail(rand2, jitter, 0, 1); /* no sync... */ generate_non_tail(rand2, jitter, 0, 1, 0); /* no sync... */
CHECK_LIMIT(); CHECK_LIMIT();
jit_movr_p(JIT_R1, JIT_R0); jit_movr_p(JIT_R1, JIT_R0);
} }
@ -5960,7 +5971,7 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i
mz_runstack_skipped(jitter, 2); mz_runstack_skipped(jitter, 2);
generate_non_tail(a2, jitter, 0, 1); generate_non_tail(a2, jitter, 0, 1, 0);
CHECK_LIMIT(); CHECK_LIMIT();
if (need_sync) mz_rs_sync(); if (need_sync) mz_rs_sync();
@ -6226,7 +6237,7 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i
mz_runstack_skipped(jitter, 2); mz_runstack_skipped(jitter, 2);
generate_non_tail(app->rand1, jitter, 0, 1); generate_non_tail(app->rand1, jitter, 0, 1, 0);
CHECK_LIMIT(); CHECK_LIMIT();
mz_rs_sync(); mz_rs_sync();
@ -6525,7 +6536,7 @@ static int generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int
CHECK_LIMIT(); CHECK_LIMIT();
} }
generate_non_tail(app->args[1], jitter, 0, 1); /* sync'd below */ generate_non_tail(app->args[1], jitter, 0, 1, 0); /* sync'd below */
CHECK_LIMIT(); CHECK_LIMIT();
if (!constval || !simple) { if (!constval || !simple) {
mz_rs_str(JIT_R0); mz_rs_str(JIT_R0);
@ -6534,7 +6545,7 @@ static int generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int
} }
if (!simple) { if (!simple) {
generate_non_tail(app->args[2], jitter, 0, 1); /* sync'd below */ generate_non_tail(app->args[2], jitter, 0, 1, 0); /* sync'd below */
CHECK_LIMIT(); CHECK_LIMIT();
if (!constval) { if (!constval) {
mz_rs_stxi(1, JIT_R0); mz_rs_stxi(1, JIT_R0);
@ -6543,7 +6554,7 @@ static int generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int
} }
} }
generate_non_tail(app->args[3], jitter, 0, 1); /* sync'd below */ generate_non_tail(app->args[3], jitter, 0, 1, 0); /* sync'd below */
CHECK_LIMIT(); CHECK_LIMIT();
mz_rs_sync(); mz_rs_sync();
@ -6631,19 +6642,34 @@ static int generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int
return 1; return 1;
} else if (IS_NAMED_PRIM(rator, "unsafe-f64vector-set!")) { } else if (IS_NAMED_PRIM(rator, "unsafe-f64vector-set!")) {
if (avoids_r1(app->args[1]) if (can_unbox(app->args[3], 5, JIT_FPR_NUM-1)) {
&& is_constant_and_avoids_r1(app->args[2]) int got_two;
&& can_unbox(app->args[3], 5, JIT_FPR_NUM-1)) { if (is_constant_and_avoids_r1(app->args[1])
mz_runstack_skipped(jitter, 3); && is_constant_and_avoids_r1(app->args[2])) {
mz_runstack_skipped(jitter, 3);
got_two = 0;
} else {
got_two = 1;
mz_runstack_skipped(jitter, 1);
generate_app(app, NULL, 2, jitter, 0, 0, 2);
}
jitter->unbox++; jitter->unbox++;
generate(app->args[3], jitter, 0, 0, JIT_R0); /* to FP reg */ generate(app->args[3], jitter, 0, 0, JIT_R0); /* to FP reg */
CHECK_LIMIT(); CHECK_LIMIT();
--jitter->unbox; --jitter->unbox;
jitter->unbox_depth -= 1; jitter->unbox_depth -= 1;
generate(app->args[2], jitter, 0, 0, JIT_R1); if (!got_two) {
CHECK_LIMIT(); generate(app->args[2], jitter, 0, 0, JIT_R1);
generate(app->args[1], jitter, 0, 0, JIT_R0); CHECK_LIMIT();
mz_runstack_unskipped(jitter, 3); generate(app->args[1], jitter, 0, 0, JIT_R0);
mz_runstack_unskipped(jitter, 3);
} else {
mz_rs_ldr(JIT_R0);
mz_rs_ldxi(JIT_R1, 1);
mz_rs_inc(2); /* no sync */
mz_runstack_popped(jitter, 2);
mz_runstack_unskipped(jitter, 1);
}
} else { } else {
generate_app(app, NULL, 3, jitter, 0, 0, 2); generate_app(app, NULL, 3, jitter, 0, 0, 2);
CHECK_LIMIT(); CHECK_LIMIT();
@ -6796,7 +6822,7 @@ static int generate_vector_alloc(mz_jit_state *jitter, Scheme_Object *rator,
if (app2) { if (app2) {
mz_runstack_skipped(jitter, 1); mz_runstack_skipped(jitter, 1);
generate_non_tail(app2->rand, jitter, 0, 1); /* sync'd below */ generate_non_tail(app2->rand, jitter, 0, 1, 0); /* sync'd below */
CHECK_LIMIT(); CHECK_LIMIT();
mz_runstack_unskipped(jitter, 1); mz_runstack_unskipped(jitter, 1);
c = 1; c = 1;
@ -7121,14 +7147,15 @@ static void generate_non_tail_mark_pos_suffix(mz_jit_state *jitter)
mz_tl_sti_l(tl_scheme_current_cont_mark_pos, JIT_R2, JIT_R0); mz_tl_sti_l(tl_scheme_current_cont_mark_pos, JIT_R2, JIT_R0);
} }
static int generate_non_tail(Scheme_Object *obj, mz_jit_state *jitter, int multi_ok, int mark_pos_ends) static int generate_non_tail(Scheme_Object *obj, mz_jit_state *jitter,
int multi_ok, int mark_pos_ends, int ignored)
/* de-sync's rs */ /* de-sync's rs */
{ {
if (is_simple(obj, INIT_SIMPLE_DEPTH, 0, jitter, 0)) { if (is_simple(obj, INIT_SIMPLE_DEPTH, 0, jitter, 0)) {
/* Simple; doesn't change the stack or set marks: */ /* Simple; doesn't change the stack or set marks: */
int v; int v;
FOR_LOG(jitter->log_depth++); FOR_LOG(jitter->log_depth++);
v = generate(obj, jitter, 0, multi_ok, JIT_R0); v = generate(obj, jitter, 0, multi_ok, ignored ? -1 : JIT_R0);
FOR_LOG(--jitter->log_depth); FOR_LOG(--jitter->log_depth);
return v; return v;
} }
@ -7163,7 +7190,7 @@ static int generate_non_tail(Scheme_Object *obj, mz_jit_state *jitter, int multi
PAUSE_JIT_DATA(); PAUSE_JIT_DATA();
FOR_LOG(jitter->log_depth++); FOR_LOG(jitter->log_depth++);
generate(obj, jitter, 0, multi_ok, JIT_R0); /* no sync */ generate(obj, jitter, 0, multi_ok, ignored ? -1 : JIT_R0); /* no sync */
FOR_LOG(--jitter->log_depth); FOR_LOG(--jitter->log_depth);
RESUME_JIT_DATA(); RESUME_JIT_DATA();
@ -7197,28 +7224,6 @@ static int generate_non_tail(Scheme_Object *obj, mz_jit_state *jitter, int multi
/* expression codegen */ /* expression codegen */
/*========================================================================*/ /*========================================================================*/
static int generate_ignored_non_tail(Scheme_Object *obj, mz_jit_state *jitter, int multi_ok, int need_ends)
/* de-sync's */
{
Scheme_Type t = SCHEME_TYPE(obj);
if (SAME_TYPE(t, scheme_local_type)
|| SAME_TYPE(t, scheme_local_unbox_type)) {
/* Must be here to clear */
if (SCHEME_LOCAL_FLAGS(obj) & SCHEME_LOCAL_CLEAR_ON_READ) {
int pos;
START_JIT_DATA();
pos = mz_remap(SCHEME_LOCAL_POS(obj));
LOG_IT(("clear %d\n", pos));
mz_rs_stxi(pos, JIT_RUNSTACK);
END_JIT_DATA(2);
}
return 1;
}
return generate_non_tail(obj, jitter, multi_ok, need_ends);
}
static Scheme_Object *generate_k(void) static Scheme_Object *generate_k(void)
{ {
Scheme_Thread *p = scheme_current_thread; Scheme_Thread *p = scheme_current_thread;
@ -7238,6 +7243,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
/* de-sync's; result goes to target */ /* de-sync's; result goes to target */
{ {
Scheme_Type type; Scheme_Type type;
int result_ignored, orig_target;
#ifdef DO_STACK_CHECK #ifdef DO_STACK_CHECK
# include "mzstkchk.h" # include "mzstkchk.h"
@ -7266,33 +7272,43 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
} }
#endif #endif
orig_target = target;
result_ignored = (target < 0);
if (target < 0) target = JIT_R0;
type = SCHEME_TYPE(obj); type = SCHEME_TYPE(obj);
switch (type) { switch (type) {
case scheme_toplevel_type: case scheme_toplevel_type:
{ {
int pos; int can_fail;
/* 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(); can_fail = !(SCHEME_TOPLEVEL_FLAGS(obj)
LOG_IT(("top-level\n")); & (SCHEME_TOPLEVEL_CONST | SCHEME_TOPLEVEL_READY));
mz_rs_sync_fail_branch(); if (!can_fail && result_ignored) {
/* Load global array: */ /* skip */
pos = mz_remap(SCHEME_TOPLEVEL_DEPTH(obj)); } else {
mz_rs_ldxi(JIT_R2, pos); int pos;
/* Load bucket: */ START_JIT_DATA();
pos = SCHEME_TOPLEVEL_POS(obj); LOG_IT(("top-level\n"));
jit_ldxi_p(JIT_R2, JIT_R2, WORDS_TO_BYTES(pos)); mz_rs_sync_fail_branch();
/* Extract bucket value */ /* Load global array: */
jit_ldxi_p(target, JIT_R2, &(SCHEME_VAR_BUCKET(0x0)->val)); pos = mz_remap(SCHEME_TOPLEVEL_DEPTH(obj));
CHECK_LIMIT(); mz_rs_ldxi(JIT_R2, pos);
if (!(SCHEME_TOPLEVEL_FLAGS(obj) /* Load bucket: */
& (SCHEME_TOPLEVEL_CONST | SCHEME_TOPLEVEL_READY))) { pos = SCHEME_TOPLEVEL_POS(obj);
/* Is it NULL? */ jit_ldxi_p(JIT_R2, JIT_R2, WORDS_TO_BYTES(pos));
generate_pop_unboxed(jitter); /* Extract bucket value */
jit_ldxi_p(target, JIT_R2, &(SCHEME_VAR_BUCKET(0x0)->val));
CHECK_LIMIT(); CHECK_LIMIT();
(void)jit_beqi_p(unbound_global_code, target, 0); if (can_fail) {
/* Is it NULL? */
generate_pop_unboxed(jitter);
CHECK_LIMIT();
(void)jit_beqi_p(unbound_global_code, target, 0);
}
if (jitter->unbox) generate_unboxing(jitter);
END_JIT_DATA(0);
} }
if (jitter->unbox) generate_unboxing(jitter);
END_JIT_DATA(0);
return 1; return 1;
} }
case scheme_local_type: case scheme_local_type:
@ -7302,11 +7318,13 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
START_JIT_DATA(); START_JIT_DATA();
pos = mz_remap(SCHEME_LOCAL_POS(obj)); pos = mz_remap(SCHEME_LOCAL_POS(obj));
LOG_IT(("local %d [%d]\n", pos, SCHEME_LOCAL_FLAGS(obj))); LOG_IT(("local %d [%d]\n", pos, SCHEME_LOCAL_FLAGS(obj)));
if (pos || (mz_CURRENT_STATUS() != mz_RS_R0_HAS_RUNSTACK0)) { if (!result_ignored) {
mz_rs_ldxi(target, pos); if (pos || (mz_CURRENT_STATUS() != mz_RS_R0_HAS_RUNSTACK0)) {
VALIDATE_RESULT(target); mz_rs_ldxi(target, pos);
} else if (target != JIT_R0) { VALIDATE_RESULT(target);
jit_movr_p(target, JIT_R0); } else if (target != JIT_R0) {
jit_movr_p(target, JIT_R0);
}
} }
if (SCHEME_LOCAL_FLAGS(obj) & SCHEME_LOCAL_CLEAR_ON_READ) { if (SCHEME_LOCAL_FLAGS(obj) & SCHEME_LOCAL_CLEAR_ON_READ) {
mz_rs_stxi(pos, JIT_RUNSTACK); mz_rs_stxi(pos, JIT_RUNSTACK);
@ -7323,8 +7341,10 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
LOG_IT(("unbox local\n")); LOG_IT(("unbox local\n"));
pos = mz_remap(SCHEME_LOCAL_POS(obj)); pos = mz_remap(SCHEME_LOCAL_POS(obj));
mz_rs_ldxi(JIT_R0, pos); if (!result_ignored) {
jit_ldr_p(target, JIT_R0); mz_rs_ldxi(JIT_R0, pos);
jit_ldr_p(target, JIT_R0);
}
if (SCHEME_LOCAL_FLAGS(obj) & SCHEME_LOCAL_CLEAR_ON_READ) { if (SCHEME_LOCAL_FLAGS(obj) & SCHEME_LOCAL_CLEAR_ON_READ) {
LOG_IT(("clear-on-read\n")); LOG_IT(("clear-on-read\n"));
mz_rs_stxi(pos, JIT_RUNSTACK); mz_rs_stxi(pos, JIT_RUNSTACK);
@ -7363,7 +7383,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
/* Evaluate first expression, and for consistency with bytecode /* Evaluate first expression, and for consistency with bytecode
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, 0);
CHECK_LIMIT(); CHECK_LIMIT();
/* Save value(s) */ /* Save value(s) */
@ -7402,7 +7422,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
mz_patch_branch(ref2); mz_patch_branch(ref2);
__END_SHORT_JUMPS__(1); __END_SHORT_JUMPS__(1);
for (i = 1; i < seq->count; i++) { for (i = 1; i < seq->count; i++) {
generate_ignored_non_tail(seq->array[i], jitter, 1, 1); /* sync's below */ generate_non_tail(seq->array[i], jitter, 1, 1, 1); /* sync's below */
CHECK_LIMIT(); CHECK_LIMIT();
} }
@ -7444,7 +7464,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
v = SCHEME_CAR(p); v = SCHEME_CAR(p);
p = SCHEME_CDR(p); p = SCHEME_CDR(p);
generate_non_tail(p, jitter, 0, 1); generate_non_tail(p, jitter, 0, 1, 0);
CHECK_LIMIT(); CHECK_LIMIT();
mz_rs_sync(); mz_rs_sync();
@ -7482,7 +7502,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
v = SCHEME_CAR(p); v = SCHEME_CAR(p);
p = SCHEME_CDR(p); p = SCHEME_CDR(p);
generate_non_tail(v, jitter, 0, 1); generate_non_tail(v, jitter, 0, 1, 0);
CHECK_LIMIT(); CHECK_LIMIT();
/* If v is not known to produce a procedure, then check result: */ /* If v is not known to produce a procedure, then check result: */
@ -7496,7 +7516,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
} }
mz_pushr_p(JIT_R0); mz_pushr_p(JIT_R0);
generate_non_tail(p, jitter, 1, 1); generate_non_tail(p, jitter, 1, 1, 0);
CHECK_LIMIT(); CHECK_LIMIT();
mz_popr_p(JIT_V1); mz_popr_p(JIT_V1);
@ -7635,7 +7655,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
jit_stxi_p(WORDS_TO_BYTES(pos), JIT_RUNSTACK, JIT_R0); jit_stxi_p(WORDS_TO_BYTES(pos), JIT_RUNSTACK, JIT_R0);
CHECK_LIMIT(); CHECK_LIMIT();
generate(p, jitter, is_tail, multi_ok, target); generate(p, jitter, is_tail, multi_ok, orig_target);
END_JIT_DATA(8); END_JIT_DATA(8);
} }
@ -7772,19 +7792,20 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
LOG_IT(("begin\n")); LOG_IT(("begin\n"));
for (i = 0; i < cnt - 1; i++) { for (i = 0; i < cnt - 1; i++) {
generate_ignored_non_tail(seq->array[i], jitter, 1, 1); generate_non_tail(seq->array[i], jitter, 1, 1, 1);
CHECK_LIMIT(); CHECK_LIMIT();
} }
END_JIT_DATA(11); END_JIT_DATA(11);
return generate(seq->array[cnt - 1], jitter, is_tail, multi_ok, target); return generate(seq->array[cnt - 1], jitter, is_tail, multi_ok, orig_target);
} }
case scheme_branch_type: case scheme_branch_type:
{ {
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, need_sync; int nsrs, nsrs1, g1, g2, amt, need_sync;
int else_is_empty = 0;
#ifdef NEED_LONG_JUMPS #ifdef NEED_LONG_JUMPS
int then_short_ok, else_short_ok; int then_short_ok, else_short_ok;
#else #else
@ -7818,9 +7839,13 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
else else
need_sync = 1; need_sync = 1;
if (result_ignored
&& (SCHEME_TYPE(branch->fbranch) > _scheme_compiled_values_types_))
else_is_empty = 1;
if (!generate_inlined_test(jitter, branch->test, then_short_ok, refs, need_sync)) { 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, 0);
if (need_sync) 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);
@ -7835,7 +7860,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
PAUSE_JIT_DATA(); PAUSE_JIT_DATA();
LOG_IT(("...then...\n")); LOG_IT(("...then...\n"));
FOR_LOG(++jitter->log_depth); FOR_LOG(++jitter->log_depth);
g1 = generate(branch->tbranch, jitter, is_tail, multi_ok, target); g1 = generate(branch->tbranch, jitter, is_tail, multi_ok, orig_target);
RESUME_JIT_DATA(); RESUME_JIT_DATA();
CHECK_LIMIT(); CHECK_LIMIT();
amt = mz_runstack_restored(jitter); amt = mz_runstack_restored(jitter);
@ -7846,7 +7871,10 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
if (need_sync) 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()); if (else_is_empty)
ref2 = NULL;
else
ref2 = jit_jmpi(jit_forward());
__END_SHORT_JUMPS__(else_short_ok); __END_SHORT_JUMPS__(else_short_ok);
nsrs1 = jitter->need_set_rs; nsrs1 = jitter->need_set_rs;
} else { } else {
@ -7882,7 +7910,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
FOR_LOG(jitter->log_depth--); FOR_LOG(jitter->log_depth--);
LOG_IT(("...else\n")); LOG_IT(("...else\n"));
FOR_LOG(++jitter->log_depth); FOR_LOG(++jitter->log_depth);
g2 = generate(branch->fbranch, jitter, is_tail, multi_ok, target); g2 = generate(branch->fbranch, jitter, is_tail, multi_ok, orig_target);
RESUME_JIT_DATA(); RESUME_JIT_DATA();
CHECK_LIMIT(); CHECK_LIMIT();
amt = mz_runstack_restored(jitter); amt = mz_runstack_restored(jitter);
@ -7897,7 +7925,9 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
} }
if (g1 != 2) { if (g1 != 2) {
__START_SHORT_JUMPS__(else_short_ok); __START_SHORT_JUMPS__(else_short_ok);
mz_patch_ucbranch(ref2); if (!else_is_empty) {
mz_patch_ucbranch(ref2);
}
__END_SHORT_JUMPS__(else_short_ok); __END_SHORT_JUMPS__(else_short_ok);
} }
FOR_LOG(jitter->log_depth--); FOR_LOG(jitter->log_depth--);
@ -7946,7 +7976,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
if (lv->count == 1) { if (lv->count == 1) {
/* Expect one result: */ /* Expect one result: */
generate_non_tail(lv->value, jitter, 0, 1); /* no sync */ generate_non_tail(lv->value, jitter, 0, 1, 0); /* no sync */
CHECK_LIMIT(); CHECK_LIMIT();
if (ab) { if (ab) {
pos = mz_remap(lv->position); pos = mz_remap(lv->position);
@ -7961,7 +7991,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
/* Expect multiple results: */ /* Expect multiple results: */
jit_insn *ref, *ref2, *ref3; jit_insn *ref, *ref2, *ref3;
generate_non_tail(lv->value, jitter, 1, 1); generate_non_tail(lv->value, jitter, 1, 1, 0);
CHECK_LIMIT(); CHECK_LIMIT();
mz_rs_sync(); mz_rs_sync();
@ -8001,7 +8031,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
CHECK_LIMIT(); CHECK_LIMIT();
/* Continue with expected values; R2 has value array: */ /* Continue with expected values; R2 has value array: */
mz_patch_branch(ref2); mz_patch_branch(ref2);
__END_SHORT_JUMPS__(1); __END_SHORT_JUMPS__(1);
for (i = 0; i < lv->count; i++) { for (i = 0; i < lv->count; i++) {
jit_ldxi_p(JIT_R1, JIT_R2, WORDS_TO_BYTES(i)); jit_ldxi_p(JIT_R1, JIT_R2, WORDS_TO_BYTES(i));
@ -8021,7 +8051,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
LOG_IT(("...in\n")); LOG_IT(("...in\n"));
return generate(lv->body, jitter, is_tail, multi_ok, target); return generate(lv->body, jitter, is_tail, multi_ok, orig_target);
} }
case scheme_let_void_type: case scheme_let_void_type:
{ {
@ -8056,7 +8086,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
LOG_IT(("...in\n")); LOG_IT(("...in\n"));
return generate(lv->body, jitter, is_tail, multi_ok, target); return generate(lv->body, jitter, is_tail, multi_ok, orig_target);
} }
case scheme_letrec_type: case scheme_letrec_type:
{ {
@ -8111,7 +8141,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
jitter->need_set_rs = nsrs; jitter->need_set_rs = nsrs;
} }
return generate(l->body, jitter, is_tail, multi_ok, target); return generate(l->body, jitter, is_tail, multi_ok, orig_target);
} }
case scheme_let_one_type: case scheme_let_one_type:
{ {
@ -8123,7 +8153,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
mz_runstack_skipped(jitter, 1); mz_runstack_skipped(jitter, 1);
PAUSE_JIT_DATA(); PAUSE_JIT_DATA();
generate_non_tail(lv->value, jitter, 0, 1); /* no sync */ generate_non_tail(lv->value, jitter, 0, 1, 0); /* no sync */
RESUME_JIT_DATA(); RESUME_JIT_DATA();
CHECK_LIMIT(); CHECK_LIMIT();
@ -8141,7 +8171,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
mz_RECORD_STATUS(mz_RS_R0_HAS_RUNSTACK0); mz_RECORD_STATUS(mz_RS_R0_HAS_RUNSTACK0);
return generate(lv->body, jitter, is_tail, multi_ok, target); return generate(lv->body, jitter, is_tail, multi_ok, orig_target);
} }
case scheme_with_cont_mark_type: case scheme_with_cont_mark_type:
{ {
@ -8151,16 +8181,16 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
LOG_IT(("wcm...\n")); LOG_IT(("wcm...\n"));
/* Key: */ /* Key: */
generate_non_tail(wcm->key, jitter, 0, 1); /* sync'd below */ generate_non_tail(wcm->key, jitter, 0, 1, 0); /* sync'd below */
CHECK_LIMIT(); CHECK_LIMIT();
if (SCHEME_TYPE(wcm->val) > _scheme_values_types_) { if (SCHEME_TYPE(wcm->val) > _scheme_values_types_) {
/* No need to push mark onto value stack: */ /* No need to push mark onto value stack: */
jit_movr_p(JIT_V1, JIT_R0); jit_movr_p(JIT_V1, JIT_R0);
generate_non_tail(wcm->val, jitter, 0, 1); /* sync'd below */ generate_non_tail(wcm->val, jitter, 0, 1, 0); /* sync'd below */
CHECK_LIMIT(); CHECK_LIMIT();
} else { } else {
mz_pushr_p(JIT_R0); mz_pushr_p(JIT_R0);
generate_non_tail(wcm->val, jitter, 0, 1); /* sync'd below */ generate_non_tail(wcm->val, jitter, 0, 1, 0); /* sync'd below */
CHECK_LIMIT(); CHECK_LIMIT();
mz_popr_p(JIT_V1); /* sync'd below */ mz_popr_p(JIT_V1); /* sync'd below */
} }
@ -8178,7 +8208,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
LOG_IT(("...in\n")); LOG_IT(("...in\n"));
return generate(wcm->body, jitter, is_tail, multi_ok, target); return generate(wcm->body, jitter, is_tail, multi_ok, orig_target);
} }
case scheme_quote_syntax_type: case scheme_quote_syntax_type:
{ {
@ -8215,7 +8245,7 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
jit_movi_d_fppush(fpr0, d); jit_movi_d_fppush(fpr0, d);
jitter->unbox_depth++; jitter->unbox_depth++;
return 1; return 1;
} else { } else if (!result_ignored) {
int retptr; int retptr;
Scheme_Type type = SCHEME_TYPE(obj); Scheme_Type type = SCHEME_TYPE(obj);
START_JIT_DATA(); START_JIT_DATA();
@ -8255,6 +8285,8 @@ static int generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int m
END_JIT_DATA(19); END_JIT_DATA(19);
return 1; return 1;
} else {
return 1;
} }
} }
} }