minor JIT back-end improvements to avoid redundant loads
This commit is contained in:
parent
b1ac25023d
commit
feac196a31
|
@ -777,6 +777,36 @@ int scheme_is_constant_and_avoids_r1(Scheme_Object *obj)
|
||||||
return (t >= _scheme_compiled_values_types_);
|
return (t >= _scheme_compiled_values_types_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int expression_avoids_clearing_local(Scheme_Object *wrt, int pos, int fuel)
|
||||||
|
{
|
||||||
|
Scheme_Type t;
|
||||||
|
t = SCHEME_TYPE(wrt);
|
||||||
|
|
||||||
|
if (t > _scheme_values_types_)
|
||||||
|
return 1;
|
||||||
|
else if (SAME_TYPE(t, scheme_local_type))
|
||||||
|
return ((SCHEME_LOCAL_POS(wrt) != pos)
|
||||||
|
|| !(SCHEME_GET_LOCAL_FLAGS(wrt) & SCHEME_LOCAL_CLEAR_ON_READ));
|
||||||
|
else if (SAME_TYPE(t, scheme_toplevel_type))
|
||||||
|
return 1;
|
||||||
|
else if (t == scheme_application2_type) {
|
||||||
|
Scheme_App2_Rec *app = (Scheme_App2_Rec *)wrt;
|
||||||
|
if (fuel < 0) return 0;
|
||||||
|
if (expression_avoids_clearing_local(app->rator, pos + 1, fuel - 1)
|
||||||
|
&& expression_avoids_clearing_local(app->rand, pos + 1, fuel - 1))
|
||||||
|
return 1;
|
||||||
|
} else if (t == scheme_application3_type) {
|
||||||
|
Scheme_App3_Rec *app = (Scheme_App3_Rec *)wrt;
|
||||||
|
if (fuel < 0) return 0;
|
||||||
|
if (expression_avoids_clearing_local(app->rator, pos + 2, fuel - 1)
|
||||||
|
&& expression_avoids_clearing_local(app->rand1, pos + 2, fuel - 1)
|
||||||
|
&& expression_avoids_clearing_local(app->rand2, pos + 2, fuel - 1))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int scheme_is_relatively_constant_and_avoids_r1_maybe_fp(Scheme_Object *obj, Scheme_Object *wrt,
|
int scheme_is_relatively_constant_and_avoids_r1_maybe_fp(Scheme_Object *obj, Scheme_Object *wrt,
|
||||||
int fp_ok)
|
int fp_ok)
|
||||||
{
|
{
|
||||||
|
@ -791,14 +821,9 @@ int scheme_is_relatively_constant_and_avoids_r1_maybe_fp(Scheme_Object *obj, Sch
|
||||||
otherwise is_constant_and_avoids_r1() would have returned 1. */
|
otherwise is_constant_and_avoids_r1() would have returned 1. */
|
||||||
if (SCHEME_GET_LOCAL_FLAGS(obj) == SCHEME_LOCAL_FLONUM)
|
if (SCHEME_GET_LOCAL_FLAGS(obj) == SCHEME_LOCAL_FLONUM)
|
||||||
return fp_ok;
|
return fp_ok;
|
||||||
else {
|
else if (expression_avoids_clearing_local(wrt, SCHEME_LOCAL_POS(obj), 3))
|
||||||
Scheme_Type t2 = SCHEME_TYPE(wrt);
|
/* different local vars, sp order doesn't matter */
|
||||||
if (t2 == scheme_local_type) {
|
return 1;
|
||||||
/* If different local vars, then order doesn't matter */
|
|
||||||
if (SCHEME_LOCAL_POS(wrt) != SCHEME_LOCAL_POS(obj))
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1328,7 +1353,7 @@ static int generate_non_tail_with_branch(Scheme_Object *obj, mz_jit_state *jitte
|
||||||
CHECK_LIMIT();
|
CHECK_LIMIT();
|
||||||
scheme_mz_flostack_restore(jitter, flostack, flostack_pos, !for_branch, 1);
|
scheme_mz_flostack_restore(jitter, flostack, flostack_pos, !for_branch, 1);
|
||||||
FOR_LOG(--jitter->log_depth);
|
FOR_LOG(--jitter->log_depth);
|
||||||
mz_CLEAR_STATUS();
|
/* mz_CLEAR_R0_STATUS(); --- not needed, since stack doesn't change */
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1417,7 +1442,7 @@ static int generate_non_tail_with_branch(Scheme_Object *obj, mz_jit_state *jitte
|
||||||
}
|
}
|
||||||
|
|
||||||
jitter->pushed_marks = save_pushed_marks;
|
jitter->pushed_marks = save_pushed_marks;
|
||||||
mz_CLEAR_STATUS();
|
mz_CLEAR_R0_STATUS();
|
||||||
|
|
||||||
END_JIT_DATA(21);
|
END_JIT_DATA(21);
|
||||||
}
|
}
|
||||||
|
@ -1637,6 +1662,7 @@ static int generate_branch(Scheme_Object *obj, mz_jit_state *jitter, int is_tail
|
||||||
if (need_sync) mz_rs_sync_0();
|
if (need_sync) mz_rs_sync_0();
|
||||||
|
|
||||||
/* False branch */
|
/* False branch */
|
||||||
|
mz_CLEAR_R0_STATUS();
|
||||||
scheme_mz_runstack_saved(jitter);
|
scheme_mz_runstack_saved(jitter);
|
||||||
flostack = scheme_mz_flostack_save(jitter, &flostack_pos);
|
flostack = scheme_mz_flostack_save(jitter, &flostack_pos);
|
||||||
__START_SHORT_JUMPS__(then_short_ok);
|
__START_SHORT_JUMPS__(then_short_ok);
|
||||||
|
@ -1700,6 +1726,8 @@ static int generate_branch(Scheme_Object *obj, mz_jit_state *jitter, int is_tail
|
||||||
if (nsrs1)
|
if (nsrs1)
|
||||||
jitter->need_set_rs = 1;
|
jitter->need_set_rs = 1;
|
||||||
|
|
||||||
|
mz_CLEAR_R0_STATUS();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1800,9 +1828,17 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w
|
||||||
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 (!result_ignored && (!flonum || !jitter->unbox)) {
|
if (!result_ignored && (!flonum || !jitter->unbox)) {
|
||||||
if (pos || (mz_CURRENT_STATUS() != mz_RS_R0_HAS_RUNSTACK0)) {
|
int old_r0 = -1;
|
||||||
|
if (mz_CURRENT_R0_STATUS_VALID()) old_r0 = mz_CURRENT_R0_STATUS();
|
||||||
|
if (pos != old_r0) {
|
||||||
mz_rs_ldxi(target, pos);
|
mz_rs_ldxi(target, pos);
|
||||||
VALIDATE_RESULT(target);
|
VALIDATE_RESULT(target);
|
||||||
|
if (target == JIT_R0)
|
||||||
|
mz_RECORD_R0_STATUS(pos);
|
||||||
|
else {
|
||||||
|
/* R0 is unchanged */
|
||||||
|
mz_RECORD_R0_STATUS(old_r0);
|
||||||
|
}
|
||||||
} else if (target != JIT_R0) {
|
} else if (target != JIT_R0) {
|
||||||
jit_movr_p(target, JIT_R0);
|
jit_movr_p(target, JIT_R0);
|
||||||
}
|
}
|
||||||
|
@ -2684,7 +2720,7 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w
|
||||||
|
|
||||||
if (!unused) {
|
if (!unused) {
|
||||||
mz_rs_str(JIT_R0);
|
mz_rs_str(JIT_R0);
|
||||||
mz_RECORD_STATUS(mz_RS_R0_HAS_RUNSTACK0);
|
mz_RECORD_R0_STATUS(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
END_JIT_DATA(17);
|
END_JIT_DATA(17);
|
||||||
|
|
|
@ -333,11 +333,10 @@ typedef struct {
|
||||||
Branch_Info_Addr *addrs;
|
Branch_Info_Addr *addrs;
|
||||||
} Branch_Info;
|
} Branch_Info;
|
||||||
|
|
||||||
#define mz_RECORD_STATUS(s) (jitter->status_at_ptr = _jit.x.pc, jitter->reg_status = (s))
|
#define mz_RECORD_R0_STATUS(s) (jitter->status_at_ptr = _jit.x.pc, jitter->reg_status = (s))
|
||||||
#define mz_CURRENT_STATUS() ((jitter->status_at_ptr == _jit.x.pc) ? jitter->reg_status : 0)
|
#define mz_CURRENT_R0_STATUS_VALID() (jitter->status_at_ptr == _jit.x.pc)
|
||||||
#define mz_CLEAR_STATUS() (jitter->reg_status = 0)
|
#define mz_CURRENT_R0_STATUS() (jitter->reg_status)
|
||||||
|
#define mz_CLEAR_R0_STATUS() (jitter->status_at_ptr = 0)
|
||||||
#define mz_RS_R0_HAS_RUNSTACK0 0x1
|
|
||||||
|
|
||||||
/* If JIT_THREAD_LOCAL is defined, then access to global variables
|
/* If JIT_THREAD_LOCAL is defined, then access to global variables
|
||||||
goes through a thread_local_pointers table. Call
|
goes through a thread_local_pointers table. Call
|
||||||
|
@ -505,15 +504,19 @@ static void *top4;
|
||||||
register. */
|
register. */
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
# define mz_rs_dec(n) (jitter->rs_virtual_offset -= (n))
|
# 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->rs_virtual_offset += (n))
|
# define mz_rs_inc(n) (jitter->reg_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_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_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)
|
# define mz_rs_stxi(n, reg) jit_stxi_p(WORDS_TO_BYTES(((n) + jitter->rs_virtual_offset)), JIT_RUNSTACK, reg)
|
||||||
# define mz_rs_str(reg) mz_rs_stxi(0, reg)
|
# define mz_rs_str(reg) mz_rs_stxi(0, reg)
|
||||||
# define mz_rs_sync() (jitter->rs_virtual_offset \
|
# define mz_rs_sync() (jitter->rs_virtual_offset \
|
||||||
? (jit_addi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(jitter->rs_virtual_offset)), \
|
? ((jitter->status_at_ptr == _jit.x.pc) \
|
||||||
jitter->rs_virtual_offset = 0) \
|
? (jit_addi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(jitter->rs_virtual_offset)), \
|
||||||
|
jitter->status_at_ptr = _jit.x.pc, \
|
||||||
|
jitter->rs_virtual_offset = 0) \
|
||||||
|
: (jit_addi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(jitter->rs_virtual_offset)), \
|
||||||
|
jitter->rs_virtual_offset = 0)) \
|
||||||
: 0)
|
: 0)
|
||||||
# define mz_rs_sync_0() (jitter->rs_virtual_offset = 0)
|
# define mz_rs_sync_0() (jitter->rs_virtual_offset = 0)
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -167,7 +167,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)
|
Branch_Info *for_branch, int branch_short, int need_sync)
|
||||||
{
|
{
|
||||||
GC_CAN_IGNORE jit_insn *ref, *ref2, *ref3, *ref4, *ref5;
|
GC_CAN_IGNORE jit_insn *ref, *ref2, *ref3, *ref4, *ref5;
|
||||||
int int_ok;
|
int int_ok, r0_set, r0;
|
||||||
|
|
||||||
int_ok = ((lo_ty <= scheme_integer_type) && (scheme_integer_type <= hi_ty));
|
int_ok = ((lo_ty <= scheme_integer_type) && (scheme_integer_type <= hi_ty));
|
||||||
|
|
||||||
|
@ -184,7 +184,13 @@ static int generate_inlined_type_test(mz_jit_state *jitter, Scheme_App2_Rec *app
|
||||||
|
|
||||||
__START_SHORT_JUMPS__(branch_short);
|
__START_SHORT_JUMPS__(branch_short);
|
||||||
|
|
||||||
|
r0_set = 0;
|
||||||
|
r0 = 0;
|
||||||
if (for_branch) {
|
if (for_branch) {
|
||||||
|
if (mz_CURRENT_R0_STATUS_VALID()) {
|
||||||
|
r0_set = 1;
|
||||||
|
r0 = mz_CURRENT_R0_STATUS();
|
||||||
|
}
|
||||||
scheme_prepare_branch_jump(jitter, for_branch);
|
scheme_prepare_branch_jump(jitter, for_branch);
|
||||||
CHECK_LIMIT();
|
CHECK_LIMIT();
|
||||||
}
|
}
|
||||||
|
@ -230,6 +236,13 @@ static int generate_inlined_type_test(mz_jit_state *jitter, Scheme_App2_Rec *app
|
||||||
scheme_add_branch_false(for_branch, ref3);
|
scheme_add_branch_false(for_branch, ref3);
|
||||||
scheme_add_branch_false(for_branch, ref4);
|
scheme_add_branch_false(for_branch, ref4);
|
||||||
scheme_add_branch_false(for_branch, ref5);
|
scheme_add_branch_false(for_branch, ref5);
|
||||||
|
|
||||||
|
/* In case true is a fall-through, note that the test
|
||||||
|
didn't disturb R0: */
|
||||||
|
if (r0_set) {
|
||||||
|
mz_RECORD_R0_STATUS(r0);
|
||||||
|
}
|
||||||
|
|
||||||
scheme_branch_for_true(jitter, for_branch);
|
scheme_branch_for_true(jitter, for_branch);
|
||||||
CHECK_LIMIT();
|
CHECK_LIMIT();
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user