JIT: Allow the jitter to reverse the arguments of string=?
This commit is contained in:
parent
6cad51189d
commit
d4158c2b04
|
@ -4649,6 +4649,22 @@
|
|||
(set! f 0))
|
||||
#f)
|
||||
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Special case of folding for string=? and bytes=?
|
||||
|
||||
(test-comp '(lambda () (string=? "123" "123"))
|
||||
'(lambda () #t))
|
||||
(test-comp '(lambda () (string=? "123" "123456"))
|
||||
'(lambda () #f))
|
||||
(test-comp '(lambda () (string=? "123" "456"))
|
||||
'(lambda () #f))
|
||||
(test-comp '(lambda () (bytes=? #"123" #"123"))
|
||||
'(lambda () #t))
|
||||
(test-comp '(lambda () (bytes=? #"123" #"123456"))
|
||||
'(lambda () #f))
|
||||
(test-comp '(lambda () (bytes=? #"123" #"456"))
|
||||
'(lambda () #f))
|
||||
|
||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Check that the type information is shifted in the
|
||||
;; right direction while inlining.
|
||||
|
|
|
@ -358,7 +358,9 @@ struct scheme_jit_common_record {
|
|||
void *apply_to_list_tail_code, *apply_to_list_code, *apply_to_list_multi_ok_code;
|
||||
void *eqv_code, *eqv_branch_code;
|
||||
void *bad_string_eq_2_code;
|
||||
void *bad_string_rev_eq_2_code;
|
||||
void *bad_bytes_eq_2_code;
|
||||
void *bad_bytes_rev_eq_2_code;
|
||||
void *proc_arity_includes_code;
|
||||
|
||||
#ifdef CAN_INLINE_ALLOC
|
||||
|
|
|
@ -469,8 +469,9 @@ static int common1(mz_jit_state *jitter, void *_data)
|
|||
|
||||
static int common1b(mz_jit_state *jitter, void *_data)
|
||||
{
|
||||
int i;
|
||||
int i, j;
|
||||
GC_CAN_IGNORE jit_insn *ref, *ref2;
|
||||
void *ip;
|
||||
|
||||
/* *** bad_set_{car,cdr}_code and make_[fl]rectangular_code *** */
|
||||
/* Bad argument is in R0, other is in R1 */
|
||||
|
@ -644,29 +645,40 @@ static int common1b(mz_jit_state *jitter, void *_data)
|
|||
CHECK_LIMIT();
|
||||
scheme_jit_register_sub_func(jitter, sjc.bad_bytes_length_code, scheme_false);
|
||||
|
||||
/* *** bad_string_eq_2_code *** */
|
||||
/* *** bad_[string/bytes]_[rev_]eq_2_code *** */
|
||||
/* R0 and R1 are arguments */
|
||||
sjc.bad_string_eq_2_code = jit_get_ip();
|
||||
mz_prolog(JIT_R2);
|
||||
JIT_UPDATE_THREAD_RSPTR();
|
||||
jit_prepare(2);
|
||||
jit_pusharg_p(JIT_R1);
|
||||
jit_pusharg_p(JIT_R0);
|
||||
(void)mz_finish_lwe(ts_scheme_string_eq_2, ref);
|
||||
CHECK_LIMIT();
|
||||
scheme_jit_register_sub_func(jitter, sjc.bad_string_eq_2_code, scheme_false);
|
||||
|
||||
/* *** bad_bytes_eq_2_code *** */
|
||||
/* R0 and R1 are arguments */
|
||||
sjc.bad_bytes_eq_2_code = jit_get_ip();
|
||||
mz_prolog(JIT_R2);
|
||||
JIT_UPDATE_THREAD_RSPTR();
|
||||
jit_prepare(2);
|
||||
jit_pusharg_p(JIT_R1);
|
||||
jit_pusharg_p(JIT_R0);
|
||||
(void)mz_finish_lwe(ts_scheme_byte_string_eq_2, ref);
|
||||
CHECK_LIMIT();
|
||||
scheme_jit_register_sub_func(jitter, sjc.bad_bytes_eq_2_code, scheme_false);
|
||||
for (i = 0; i < 2; i++) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
ip = jit_get_ip();
|
||||
if (i) {
|
||||
if (j)
|
||||
sjc.bad_bytes_rev_eq_2_code = ip;
|
||||
else
|
||||
sjc.bad_bytes_eq_2_code = ip;
|
||||
} else {
|
||||
if (j)
|
||||
sjc.bad_string_rev_eq_2_code = ip;
|
||||
else
|
||||
sjc.bad_string_eq_2_code = ip;
|
||||
}
|
||||
mz_prolog(JIT_R2);
|
||||
JIT_UPDATE_THREAD_RSPTR();
|
||||
jit_prepare(2);
|
||||
if (j) {
|
||||
jit_pusharg_p(JIT_R1);
|
||||
jit_pusharg_p(JIT_R0);
|
||||
} else {
|
||||
jit_pusharg_p(JIT_R0);
|
||||
jit_pusharg_p(JIT_R1);
|
||||
}
|
||||
if (i)
|
||||
(void)mz_finish_lwe(ts_scheme_byte_string_eq_2, ref);
|
||||
else
|
||||
(void)mz_finish_lwe(ts_scheme_string_eq_2, ref);
|
||||
CHECK_LIMIT();
|
||||
scheme_jit_register_sub_func(jitter, ip, scheme_false);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -2205,7 +2205,7 @@ int scheme_generate_two_args(Scheme_Object *rand1, Scheme_Object *rand2, mz_jit_
|
|||
/* de-sync's rs.
|
||||
Results go into R0 and R1. If !order_matters, and if only the
|
||||
second is simple, then the arguments will be in reverse order.
|
||||
Return is 1 if thr arguments are in order, -1 if reversed. */
|
||||
Return is 1 if the arguments are in order, -1 if reversed. */
|
||||
{
|
||||
int simple1, simple2, direction = 1;
|
||||
|
||||
|
@ -2837,49 +2837,62 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i
|
|||
return 1;
|
||||
} else if (IS_NAMED_PRIM(rator, "string=?")
|
||||
|| IS_NAMED_PRIM(rator, "bytes=?")) {
|
||||
GC_CAN_IGNORE jit_insn *ref_fx1, *ref_fx2, *ref_fail1, *ref_fail2, *ref_ucnofail;
|
||||
GC_CAN_IGNORE jit_insn *ref_fx1 = NULL, *ref_fx2 = NULL, *ref_fail1 = NULL, *ref_fail2 = NULL;
|
||||
GC_CAN_IGNORE jit_insn *ref_ucnofail;
|
||||
GC_CAN_IGNORE jit_insn *ref_false1, *ref_false2 = NULL;
|
||||
GC_CAN_IGNORE jit_insn *ref_true1, *ref_true2, *ref_ucfinish;
|
||||
GC_CAN_IGNORE jit_insn *ref_true1 = NULL, *ref_true2, *ref_ucfinish;
|
||||
GC_CAN_IGNORE jit_insn *ref_loop;
|
||||
int is_str1, is_str2, len = 0;
|
||||
Scheme_Object *rand1, *rand2;
|
||||
int is_str1, is_str2, len = 0, direction = 0;
|
||||
int string, string_type;
|
||||
void * sjc_bad_code;
|
||||
void *sjc_bad_code, *sjc_bad_rev_code;
|
||||
intptr_t string_len_val, string_val;
|
||||
|
||||
if ((IS_NAMED_PRIM(rator, "string=?"))) {
|
||||
string = 1;
|
||||
string_type = scheme_char_string_type;
|
||||
sjc_bad_code = sjc.bad_string_eq_2_code;
|
||||
sjc_bad_rev_code = sjc.bad_string_rev_eq_2_code;
|
||||
string_len_val = (intptr_t)&SCHEME_CHAR_STRLEN_VAL(0x0);
|
||||
string_val = (intptr_t)&SCHEME_CHAR_STR_VAL(0x0);
|
||||
} else { /* IS_NAMED_PRIM(rator, "bytes=?") */
|
||||
string = 0;
|
||||
string_type = scheme_byte_string_type;
|
||||
sjc_bad_code = sjc.bad_bytes_eq_2_code;
|
||||
sjc_bad_rev_code = sjc.bad_bytes_rev_eq_2_code;
|
||||
string_len_val = (intptr_t)&SCHEME_BYTE_STRLEN_VAL(0x0);
|
||||
string_val = (intptr_t)&SCHEME_BYTE_STR_VAL(0x0);
|
||||
}
|
||||
|
||||
is_str1 = (SAME_TYPE(SCHEME_TYPE(app->rand1), string_type));
|
||||
is_str2 = (SAME_TYPE(SCHEME_TYPE(app->rand2), string_type));
|
||||
if (string) {
|
||||
if (is_str1) {
|
||||
len = SCHEME_CHAR_STRLEN_VAL(app->rand1);
|
||||
} else if (is_str2) {
|
||||
len = SCHEME_CHAR_STRLEN_VAL(app->rand2);
|
||||
}
|
||||
} else {
|
||||
if (is_str1) {
|
||||
len = SCHEME_BYTE_STRLEN_VAL(app->rand1);
|
||||
} else if (is_str2) {
|
||||
len = SCHEME_BYTE_STRLEN_VAL(app->rand2);
|
||||
}
|
||||
}
|
||||
|
||||
scheme_generate_two_args(app->rand1, app->rand2, jitter, 1, 2);
|
||||
direction = scheme_generate_two_args(app->rand1, app->rand2, jitter, 0, 2);
|
||||
CHECK_LIMIT();
|
||||
|
||||
mz_rs_sync();
|
||||
|
||||
if (direction == -1) {
|
||||
rand1 = app->rand2;
|
||||
rand2 = app->rand1;
|
||||
} else {
|
||||
rand1 = app->rand1;
|
||||
rand2 = app->rand2;
|
||||
}
|
||||
|
||||
is_str1 = (SAME_TYPE(SCHEME_TYPE(rand1), string_type));
|
||||
is_str2 = (SAME_TYPE(SCHEME_TYPE(rand2), string_type));
|
||||
if (string) {
|
||||
if (is_str1) {
|
||||
len = SCHEME_CHAR_STRLEN_VAL(rand1);
|
||||
} else if (is_str2) {
|
||||
len = SCHEME_CHAR_STRLEN_VAL(rand2);
|
||||
}
|
||||
} else {
|
||||
if (is_str1) {
|
||||
len = SCHEME_BYTE_STRLEN_VAL(rand1);
|
||||
} else if (is_str2) {
|
||||
len = SCHEME_BYTE_STRLEN_VAL(rand2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (for_branch) {
|
||||
__START_SHORT_JUMPS__(branch_short);
|
||||
|
@ -2894,17 +2907,11 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i
|
|||
ref_fx1 = jit_bmsi_ul(jit_forward(), JIT_R0, 0x1);
|
||||
jit_ldxi_s(JIT_R2, JIT_R0, &((Scheme_Object *)0x0)->type);
|
||||
ref_fail1 = jit_bnei_i(jit_forward(), JIT_R2, string_type);
|
||||
} else {
|
||||
ref_fx1 = NULL;
|
||||
ref_fail1 = NULL;
|
||||
}
|
||||
if (!is_str2) {
|
||||
ref_fx2 = jit_bmsi_ul(jit_forward(), JIT_R1, 0x1);
|
||||
jit_ldxi_s(JIT_V1, JIT_R1, &((Scheme_Object *)0x0)->type);
|
||||
ref_fail2 = jit_bnei_i(jit_forward(), JIT_V1, string_type);
|
||||
} else {
|
||||
ref_fx2 = NULL;
|
||||
ref_fail2 = NULL;
|
||||
}
|
||||
ref_ucnofail = jit_jmpi(jit_forward());
|
||||
CHECK_LIMIT();
|
||||
|
@ -2920,7 +2927,10 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i
|
|||
}
|
||||
__END_TINY_JUMPS__(1);
|
||||
|
||||
(void)jit_calli(sjc_bad_code);
|
||||
if (direction == 1)
|
||||
(void)jit_calli(sjc_bad_code);
|
||||
else
|
||||
(void)jit_calli(sjc_bad_rev_code);
|
||||
CHECK_LIMIT();
|
||||
|
||||
/* main */
|
||||
|
@ -2949,7 +2959,8 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i
|
|||
if ((!is_str1 && !is_str2) || len) {
|
||||
__START_TINY_JUMPS__(1);
|
||||
/* true if both have length zero or are eq?*/
|
||||
ref_true1 = jit_beqi_l(jit_forward(), JIT_R2, 0);
|
||||
if (!len)
|
||||
ref_true1 = jit_beqi_l(jit_forward(), JIT_R2, 0);
|
||||
ref_true2 = jit_beqr_p(jit_forward(), JIT_R0, JIT_R1);
|
||||
|
||||
/* initialize loop*/
|
||||
|
@ -2994,7 +3005,8 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i
|
|||
CHECK_LIMIT();
|
||||
|
||||
/* true */
|
||||
mz_patch_branch(ref_true1);
|
||||
if (ref_true1)
|
||||
mz_patch_branch(ref_true1);
|
||||
mz_patch_branch(ref_true2);
|
||||
__END_TINY_JUMPS__(1);
|
||||
}
|
||||
|
|
|
@ -4622,6 +4622,16 @@ static Scheme_Object *finish_optimize_application3(Scheme_App3_Rec *app, Optimiz
|
|||
info->size -= 1;
|
||||
return make_optimize_prim_application2(scheme_null_p_proc, app->rand1, info, context);
|
||||
}
|
||||
} else if (IS_NAMED_PRIM(app->rator, "string=?")) {
|
||||
if (SAME_TYPE(SCHEME_TYPE(app->rand1), scheme_char_string_type)
|
||||
&& SAME_TYPE(SCHEME_TYPE(app->rand2), scheme_char_string_type)) {
|
||||
return scheme_string_eq_2(app->rand1, app->rand2);
|
||||
}
|
||||
} else if (IS_NAMED_PRIM(app->rator, "bytes=?")) {
|
||||
if (SAME_TYPE(SCHEME_TYPE(app->rand1), scheme_byte_string_type)
|
||||
&& SAME_TYPE(SCHEME_TYPE(app->rand2), scheme_byte_string_type)) {
|
||||
return scheme_byte_string_eq_2(app->rand1, app->rand2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user