tweak JIT to improve and slightly generalize register tracking
This commit is contained in:
parent
87a6b850a7
commit
825548f5dc
|
@ -1340,7 +1340,7 @@ static int generate_non_tail_with_branch(Scheme_Object *obj, mz_jit_state *jitte
|
|||
CHECK_LIMIT();
|
||||
scheme_mz_flostack_restore(jitter, flostack, flostack_pos, !for_branch, 1);
|
||||
FOR_LOG(--jitter->log_depth);
|
||||
/* mz_CLEAR_R0_STATUS(); --- not needed, since stack doesn't change */
|
||||
/* mz_SET_REG_STATUS_VALID(0); --- not needed, since stack doesn't change */
|
||||
return v;
|
||||
}
|
||||
|
||||
|
@ -1429,7 +1429,7 @@ static int generate_non_tail_with_branch(Scheme_Object *obj, mz_jit_state *jitte
|
|||
}
|
||||
|
||||
jitter->pushed_marks = save_pushed_marks;
|
||||
mz_CLEAR_R0_STATUS();
|
||||
mz_SET_REG_STATUS_VALID(0);
|
||||
|
||||
END_JIT_DATA(21);
|
||||
}
|
||||
|
@ -1654,7 +1654,7 @@ static int generate_branch(Scheme_Object *obj, mz_jit_state *jitter, int is_tail
|
|||
scheme_signal_error("internal error: self position moved across branch");
|
||||
|
||||
/* False branch */
|
||||
mz_CLEAR_R0_STATUS();
|
||||
mz_SET_REG_STATUS_VALID(0);
|
||||
scheme_mz_runstack_saved(jitter);
|
||||
flostack = scheme_mz_flostack_save(jitter, &flostack_pos);
|
||||
__START_SHORT_JUMPS__(then_short_ok);
|
||||
|
@ -1718,7 +1718,7 @@ static int generate_branch(Scheme_Object *obj, mz_jit_state *jitter, int is_tail
|
|||
if (nsrs1)
|
||||
jitter->need_set_rs = 1;
|
||||
|
||||
mz_CLEAR_R0_STATUS();
|
||||
mz_SET_REG_STATUS_VALID(0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1820,19 +1820,44 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w
|
|||
pos = mz_remap(SCHEME_LOCAL_POS(obj));
|
||||
LOG_IT(("local %d [%d]\n", pos, SCHEME_LOCAL_FLAGS(obj)));
|
||||
if (!result_ignored && (!flonum || !jitter->unbox)) {
|
||||
int old_r0 = -1;
|
||||
if (mz_CURRENT_R0_STATUS_VALID()) old_r0 = mz_CURRENT_R0_STATUS();
|
||||
if (pos != old_r0) {
|
||||
int valid, old_r0 = -1, old_r1 = -1;
|
||||
|
||||
if (mz_CURRENT_REG_STATUS_VALID()) {
|
||||
valid = 1;
|
||||
old_r0 = jitter->r0_status;
|
||||
old_r1 = jitter->r1_status;
|
||||
} else
|
||||
valid = 0;
|
||||
|
||||
if (pos == old_r0) {
|
||||
if (target != JIT_R0) {
|
||||
jit_movr_p(target, JIT_R0);
|
||||
if (target == JIT_R1)
|
||||
jitter->r1_status = pos;
|
||||
mz_SET_REG_STATUS_VALID(1);
|
||||
}
|
||||
} else if (pos == old_r1) {
|
||||
if (target != JIT_R1) {
|
||||
jit_movr_p(target, JIT_R1);
|
||||
if (target == JIT_R0)
|
||||
jitter->r1_status = pos;
|
||||
mz_SET_REG_STATUS_VALID(1);
|
||||
}
|
||||
} else {
|
||||
mz_rs_ldxi(target, pos);
|
||||
VALIDATE_RESULT(target);
|
||||
if (target == JIT_R0)
|
||||
mz_RECORD_R0_STATUS(pos);
|
||||
else {
|
||||
/* R0 is unchanged */
|
||||
mz_RECORD_R0_STATUS(old_r0);
|
||||
if (target == JIT_R0) {
|
||||
jitter->r0_status = pos;
|
||||
jitter->r1_status = old_r1;
|
||||
mz_SET_REG_STATUS_VALID(1);
|
||||
} else if (target == JIT_R1) {
|
||||
jitter->r1_status = pos;
|
||||
jitter->r0_status = old_r0;
|
||||
mz_SET_REG_STATUS_VALID(1);
|
||||
} else if (valid) {
|
||||
/* R0 and R1 are unchanged */
|
||||
mz_SET_REG_STATUS_VALID(1);
|
||||
}
|
||||
} else if (target != JIT_R0) {
|
||||
jit_movr_p(target, JIT_R0);
|
||||
}
|
||||
}
|
||||
if (SCHEME_GET_LOCAL_FLAGS(obj) == SCHEME_LOCAL_CLEAR_ON_READ) {
|
||||
|
@ -2721,7 +2746,9 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w
|
|||
|
||||
if (!unused) {
|
||||
mz_rs_str(JIT_R0);
|
||||
mz_RECORD_R0_STATUS(0);
|
||||
jitter->r0_status = 0;
|
||||
jitter->r1_status = -1;
|
||||
mz_SET_REG_STATUS_VALID(1);
|
||||
}
|
||||
|
||||
END_JIT_DATA(17);
|
||||
|
|
|
@ -310,7 +310,7 @@ typedef struct {
|
|||
Scheme_Native_Closure *nc; /* for extract_globals and extract_closure_local, only */
|
||||
Scheme_Closure_Data *self_data;
|
||||
void *status_at_ptr;
|
||||
int reg_status;
|
||||
int r0_status, r1_status;
|
||||
void *patch_depth;
|
||||
int rs_virtual_offset;
|
||||
int unbox, unbox_depth;
|
||||
|
@ -340,10 +340,11 @@ typedef struct {
|
|||
Branch_Info_Addr *addrs;
|
||||
} Branch_Info;
|
||||
|
||||
#define mz_RECORD_R0_STATUS(s) (jitter->status_at_ptr = _jit.x.pc, jitter->reg_status = (s))
|
||||
#define mz_CURRENT_R0_STATUS_VALID() (jitter->status_at_ptr == _jit.x.pc)
|
||||
#define mz_CURRENT_R0_STATUS() (jitter->reg_status)
|
||||
#define mz_CLEAR_R0_STATUS() (jitter->status_at_ptr = 0)
|
||||
#define mz_CURRENT_REG_STATUS_VALID() (jitter->status_at_ptr == _jit.x.pc)
|
||||
#define mz_SET_REG_STATUS_VALID(v) (jitter->status_at_ptr = (v ? _jit.x.pc : 0))
|
||||
|
||||
#define mz_SET_R0_STATUS_VALID(v) (jitter->status_at_ptr = (v ? _jit.x.pc : 0), \
|
||||
jitter->r1_status = -1)
|
||||
|
||||
/* If JIT_THREAD_LOCAL is defined, then access to global variables
|
||||
goes through a thread_local_pointers table. Call
|
||||
|
@ -511,8 +512,12 @@ static void *top4;
|
|||
register. */
|
||||
|
||||
#if 1
|
||||
# define mz_rs_dec(n) (((jitter->reg_status >= 0) ? jitter->reg_status += (n) : 0), jitter->rs_virtual_offset -= (n))
|
||||
# define mz_rs_inc(n) (jitter->reg_status -= (n), jitter->rs_virtual_offset += (n))
|
||||
# define mz_rs_dec(n) (((jitter->r0_status >= 0) ? jitter->r0_status += (n) : 0), \
|
||||
((jitter->r1_status >= 0) ? jitter->r1_status += (n) : 0), \
|
||||
jitter->rs_virtual_offset -= (n))
|
||||
# define mz_rs_inc(n) (jitter->r0_status -= (n), \
|
||||
jitter->r1_status -= (n), \
|
||||
jitter->rs_virtual_offset += (n))
|
||||
# define mz_rs_ldxi(reg, n) jit_ldxi_p(reg, JIT_RUNSTACK, WORDS_TO_BYTES(((n) + jitter->rs_virtual_offset)))
|
||||
# define mz_rs_ldr(reg) mz_rs_ldxi(reg, 0)
|
||||
# define mz_rs_stxi(n, reg) jit_stxi_p(WORDS_TO_BYTES(((n) + jitter->rs_virtual_offset)), JIT_RUNSTACK, reg)
|
||||
|
|
|
@ -1085,8 +1085,7 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
va = JIT_R0;
|
||||
} else {
|
||||
if (simple_rand) {
|
||||
pos = mz_remap(SCHEME_LOCAL_POS(rand));
|
||||
mz_rs_ldxi(JIT_R1, pos);
|
||||
scheme_generate(rand, jitter, 0, 0, 0, JIT_R1, NULL);
|
||||
}
|
||||
if (!unsafe_fx && !unsafe_fl) {
|
||||
/* check both fixnum bits at once by ANDing into R2: */
|
||||
|
|
|
@ -1639,9 +1639,9 @@ int scheme_generate_app(Scheme_App_Rec *app, Scheme_Object **alt_rands, int num_
|
|||
&& (!direct_self || !is_tail || no_call || (i + 1 < num_rands))
|
||||
&& !inline_direct_args) {
|
||||
int r0;
|
||||
r0 = (mz_CURRENT_R0_STATUS_VALID() ? mz_CURRENT_R0_STATUS() : -1);
|
||||
r0 = mz_CURRENT_REG_STATUS_VALID();
|
||||
mz_rs_stxi(i + offset, JIT_R0);
|
||||
if (r0 > -1) mz_RECORD_R0_STATUS(r0);
|
||||
mz_SET_REG_STATUS_VALID(r0);
|
||||
}
|
||||
}
|
||||
/* not sync'd... */
|
||||
|
|
|
@ -177,7 +177,7 @@ static int generate_inlined_type_test(mz_jit_state *jitter, Scheme_App2_Rec *app
|
|||
Branch_Info *for_branch, int branch_short, int need_sync)
|
||||
{
|
||||
GC_CAN_IGNORE jit_insn *ref, *ref2, *ref3, *ref4, *ref5;
|
||||
int int_ok, r0_set, r0;
|
||||
int int_ok, reg_valid;
|
||||
|
||||
int_ok = ((lo_ty <= scheme_integer_type) && (scheme_integer_type <= hi_ty));
|
||||
|
||||
|
@ -194,13 +194,9 @@ static int generate_inlined_type_test(mz_jit_state *jitter, Scheme_App2_Rec *app
|
|||
|
||||
__START_SHORT_JUMPS__(branch_short);
|
||||
|
||||
r0_set = 0;
|
||||
r0 = 0;
|
||||
reg_valid = 0;
|
||||
if (for_branch) {
|
||||
if (mz_CURRENT_R0_STATUS_VALID()) {
|
||||
r0_set = 1;
|
||||
r0 = mz_CURRENT_R0_STATUS();
|
||||
}
|
||||
reg_valid = mz_CURRENT_REG_STATUS_VALID();
|
||||
scheme_prepare_branch_jump(jitter, for_branch);
|
||||
CHECK_LIMIT();
|
||||
}
|
||||
|
@ -256,9 +252,7 @@ static int generate_inlined_type_test(mz_jit_state *jitter, Scheme_App2_Rec *app
|
|||
|
||||
/* In case true is a fall-through, note that the test
|
||||
didn't disturb R0: */
|
||||
if (r0_set) {
|
||||
mz_RECORD_R0_STATUS(r0);
|
||||
}
|
||||
mz_SET_R0_STATUS_VALID(reg_valid);
|
||||
|
||||
scheme_branch_for_true(jitter, for_branch);
|
||||
CHECK_LIMIT();
|
||||
|
@ -1261,6 +1255,7 @@ static int generate_two_args(Scheme_Object *rand1, Scheme_Object *rand2, mz_jit_
|
|||
|
||||
scheme_generate_non_tail(rand1, jitter, 0, 1, 0); /* no sync... */
|
||||
CHECK_LIMIT();
|
||||
|
||||
jit_movr_p(JIT_R1, JIT_R0);
|
||||
|
||||
scheme_generate(rand2, jitter, 0, 0, 0, JIT_R0, NULL); /* no sync... */
|
||||
|
@ -1268,9 +1263,18 @@ static int generate_two_args(Scheme_Object *rand1, Scheme_Object *rand2, mz_jit_
|
|||
|
||||
if (order_matters) {
|
||||
/* Swap arguments: */
|
||||
int reg_status;
|
||||
reg_status = mz_CURRENT_REG_STATUS_VALID();
|
||||
jit_movr_p(JIT_R2, JIT_R0);
|
||||
jit_movr_p(JIT_R0, JIT_R1);
|
||||
jit_movr_p(JIT_R1, JIT_R2);
|
||||
if (reg_status) {
|
||||
int pos;
|
||||
pos = jitter->r0_status;
|
||||
jitter->r0_status = jitter->r1_status;
|
||||
jitter->r1_status = pos;
|
||||
mz_SET_REG_STATUS_VALID(1);
|
||||
}
|
||||
} else
|
||||
direction = -1;
|
||||
|
||||
|
@ -1673,7 +1677,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i
|
|||
|
||||
if (SCHEME_TYPE(a1) > _scheme_values_types_) {
|
||||
/* Compare to constant: */
|
||||
int retptr;
|
||||
int retptr, reg_status;
|
||||
|
||||
mz_runstack_skipped(jitter, 2);
|
||||
|
||||
|
@ -1697,6 +1701,8 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i
|
|||
scheme_prepare_branch_jump(jitter, for_branch);
|
||||
CHECK_LIMIT();
|
||||
}
|
||||
|
||||
reg_status = mz_CURRENT_REG_STATUS_VALID();
|
||||
|
||||
#ifdef JIT_PRECISE_GC
|
||||
if (retptr) {
|
||||
|
@ -1707,6 +1713,14 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i
|
|||
ref = mz_bnei_p(jit_forward(), JIT_R0, a1);
|
||||
|
||||
if (for_branch) {
|
||||
/* In case true is a fall-through, note that the test
|
||||
didn't disturb R0 (and maybe not R1): */
|
||||
#ifdef JIT_PRECISE_GC
|
||||
if (retptr)
|
||||
mz_SET_R0_STATUS_VALID(reg_status);
|
||||
else
|
||||
#endif
|
||||
mz_SET_REG_STATUS_VALID(reg_status);
|
||||
scheme_add_branch_false(for_branch, ref);
|
||||
scheme_branch_for_true(jitter, for_branch);
|
||||
CHECK_LIMIT();
|
||||
|
|
Loading…
Reference in New Issue
Block a user