skip some unneeded fixnum tests in JIT-generated code
This commit is contained in:
parent
4041e65a86
commit
be4ce3ed66
|
@ -81,7 +81,15 @@
|
|||
(when (boolean? v)
|
||||
;; (printf " for branch...\n")
|
||||
(test (if v 'yes 'no) name ((eval `(lambda (x) (if (,op x ',arg2) 'yes 'no))) arg1))
|
||||
(test (if v 'yes 'no) name ((eval `(lambda (x) (if (,op ',arg1 x) 'yes 'no))) arg2)))))]
|
||||
(test (if v 'yes 'no) name ((eval `(lambda (x) (if (,op ',arg1 x) 'yes 'no))) arg2)))
|
||||
(when (fixnum? arg2)
|
||||
(test v name ((eval `(lambda (x) (let ([x2 (fx+ (random 1) ',arg2)])
|
||||
(,op x x2))))
|
||||
arg1)))
|
||||
(when (fixnum? arg1)
|
||||
(test v name ((eval `(lambda (y) (let ([x1 (fx+ (random 1) ',arg1)])
|
||||
(,op x1 y))))
|
||||
arg2)))))]
|
||||
[bin-exact (lambda (v op arg1 arg2 [check-fixnum-as-bad? #f])
|
||||
(check-error-message op (eval `(lambda (x) (,op x ',arg2))))
|
||||
(check-error-message op (eval `(lambda (x) (,op ',arg1 x))))
|
||||
|
|
|
@ -1263,6 +1263,7 @@ Scheme_Object *scheme_jit_make_two_element_ivector(Scheme_Object *a, Scheme_Obje
|
|||
/* jitarith */
|
||||
/**********************************************************************/
|
||||
|
||||
int scheme_jit_is_fixnum(Scheme_Object *rand);
|
||||
int scheme_can_unbox_inline(Scheme_Object *obj, int fuel, int regs, int unsafely);
|
||||
int scheme_can_unbox_directly(Scheme_Object *obj);
|
||||
int scheme_generate_unboxing(mz_jit_state *jitter, int target);
|
||||
|
|
|
@ -30,6 +30,18 @@
|
|||
#define JITARITH_TS_PROCS
|
||||
#include "jit_ts.c"
|
||||
|
||||
int scheme_jit_is_fixnum(Scheme_Object *rand)
|
||||
{
|
||||
if (SCHEME_INTP(rand)
|
||||
|| (SAME_TYPE(SCHEME_TYPE(rand), scheme_local_type)
|
||||
&& (SCHEME_GET_LOCAL_TYPE(rand) == SCHEME_LOCAL_TYPE_FIXNUM)))
|
||||
return 1;
|
||||
else if (scheme_expr_produces_local_type(rand) == SCHEME_LOCAL_TYPE_FIXNUM)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int can_reorder_unboxing(Scheme_Object *rand, Scheme_Object *rand2)
|
||||
{
|
||||
/* Can we reorder `rand' and `rand2', given that we want floating-point
|
||||
|
@ -1038,6 +1050,18 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
ref = NULL;
|
||||
ref4 = NULL;
|
||||
} else {
|
||||
if (!unsafe_fl
|
||||
&& ((arith == ARITH_MIN)
|
||||
|| (arith == ARITH_MAX)
|
||||
|| (arith == ARITH_AND)
|
||||
|| (arith == ARITH_IOR)
|
||||
|| (arith == ARITH_XOR))) {
|
||||
/* No slow path necessary for fixnum arguments. */
|
||||
if (scheme_jit_is_fixnum(rand) && (!rand2 || scheme_jit_is_fixnum(rand2))) {
|
||||
unsafe_fx = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (rand2) {
|
||||
if (SCHEME_INTP(rand2)
|
||||
&& SCHEME_INT_SMALL_ENOUGH(rand2)
|
||||
|
@ -1082,6 +1106,12 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
reversed = 1;
|
||||
}
|
||||
|
||||
if (!unsafe_fl && !unsafe_fx
|
||||
&& (scheme_jit_is_fixnum(rand) && (!rand2 || scheme_jit_is_fixnum(rand2)))) {
|
||||
/* Since we'll get a fix num, skip flonum variant */
|
||||
has_flonum_fast = 0;
|
||||
}
|
||||
|
||||
if (rand2) {
|
||||
int dir;
|
||||
dir = scheme_generate_two_args(rand, rand2, jitter, 0, orig_args);
|
||||
|
@ -1109,9 +1139,13 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
if (rand2) {
|
||||
int va;
|
||||
|
||||
if (SCHEME_INTP(rand)) {
|
||||
if (scheme_jit_is_fixnum(rand)) {
|
||||
if (scheme_jit_is_fixnum(rand2)) {
|
||||
va = -1; /* no check needed */
|
||||
} else {
|
||||
va = JIT_R0; /* check only rand2 */
|
||||
} else if (SCHEME_INTP(rand2)) {
|
||||
}
|
||||
} else if (scheme_jit_is_fixnum(rand2)) {
|
||||
va = JIT_R1; /* check only rand */
|
||||
} else {
|
||||
if (!unsafe_fx && !unsafe_fl) {
|
||||
|
@ -1125,6 +1159,9 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
mz_rs_sync();
|
||||
|
||||
__START_TINY_JUMPS_IF_COMPACT__(1);
|
||||
if (va == -1)
|
||||
ref2 = jit_jmpi(jit_forward());
|
||||
else
|
||||
ref2 = jit_bmsi_ul(jit_forward(), va, 0x1);
|
||||
__END_TINY_JUMPS_IF_COMPACT__(1);
|
||||
} else {
|
||||
|
@ -1145,6 +1182,9 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
if (!unsafe_fx && !unsafe_fl) {
|
||||
if (!has_fixnum_fast) {
|
||||
__START_TINY_JUMPS_IF_COMPACT__(1);
|
||||
if (va == -1)
|
||||
mz_patch_ucbranch(ref2);
|
||||
else
|
||||
mz_patch_branch(ref2);
|
||||
__END_TINY_JUMPS_IF_COMPACT__(1);
|
||||
}
|
||||
|
@ -1155,6 +1195,9 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
|
||||
if (has_fixnum_fast) {
|
||||
__START_TINY_JUMPS_IF_COMPACT__(1);
|
||||
if (va == -1)
|
||||
mz_patch_ucbranch(ref2);
|
||||
else
|
||||
mz_patch_branch(ref2);
|
||||
__END_TINY_JUMPS_IF_COMPACT__(1);
|
||||
}
|
||||
|
@ -1166,9 +1209,16 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
CHECK_LIMIT();
|
||||
} else {
|
||||
/* Only one argument: */
|
||||
int is_fx;
|
||||
|
||||
is_fx = scheme_jit_is_fixnum(rand);
|
||||
|
||||
if (!unsafe_fx && !unsafe_fl) {
|
||||
mz_rs_sync();
|
||||
__START_TINY_JUMPS_IF_COMPACT__(1);
|
||||
if (is_fx)
|
||||
ref2 = jit_jmpi(jit_forward());
|
||||
else
|
||||
ref2 = jit_bmsi_ul(jit_forward(), JIT_R0, 0x1);
|
||||
__END_TINY_JUMPS_IF_COMPACT__(1);
|
||||
} else {
|
||||
|
@ -1193,6 +1243,9 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
if (!unsafe_fx && !unsafe_fl) {
|
||||
if (!has_fixnum_fast) {
|
||||
__START_TINY_JUMPS_IF_COMPACT__(1);
|
||||
if (is_fx)
|
||||
mz_patch_ucbranch(ref2);
|
||||
else
|
||||
mz_patch_branch(ref2);
|
||||
__END_TINY_JUMPS_IF_COMPACT__(1);
|
||||
}
|
||||
|
@ -1203,6 +1256,9 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
|
||||
if (has_fixnum_fast) {
|
||||
__START_TINY_JUMPS_IF_COMPACT__(1);
|
||||
if (is_fx)
|
||||
mz_patch_ucbranch(ref2);
|
||||
else
|
||||
mz_patch_branch(ref2);
|
||||
__END_TINY_JUMPS_IF_COMPACT__(1);
|
||||
}
|
||||
|
|
|
@ -2026,7 +2026,9 @@ static int generate_binary_char(mz_jit_state *jitter, Scheme_App3_Rec *app,
|
|||
static int generate_vector_op(mz_jit_state *jitter, int set, int int_ready, int base_offset,
|
||||
int for_fl, int unsafe,
|
||||
int unbox_flonum, int result_ignored, int can_chaperone,
|
||||
int for_struct, int for_fx, int check_mutable, int dest)
|
||||
int for_struct, int for_fx, int check_mutable,
|
||||
int known_fixnum_index, int known_fixnum_val,
|
||||
int dest)
|
||||
/* R0 has vector. In set mode, R2 has value; if not unboxed, not unsafe, or can chaperone,
|
||||
RUNSTACK has space for a temporary (intended for R2).
|
||||
If int_ready, R1 has num index (for safe or can-chaperone mode) and V1 has pre-computed
|
||||
|
@ -2085,9 +2087,9 @@ static int generate_vector_op(mz_jit_state *jitter, int set, int int_ready, int
|
|||
if (for_struct && unsafe && can_chaperone)
|
||||
(void)mz_beqi_t(reffail, JIT_R0, scheme_proc_chaperone_type, JIT_R2);
|
||||
if (!unsafe) {
|
||||
if (!int_ready)
|
||||
if (!int_ready && !known_fixnum_index)
|
||||
(void)jit_bmci_ul(reffail, JIT_R1, 0x1);
|
||||
if (set && for_fx)
|
||||
if (set && for_fx && !known_fixnum_val)
|
||||
(void)jit_bmci_ul(reffail, JIT_R2, 0x1);
|
||||
if (for_fx) {
|
||||
(void)mz_bnei_t(reffail, JIT_R0, scheme_fxvector_type, JIT_R2);
|
||||
|
@ -2751,12 +2753,14 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i
|
|||
if (can_chaperone) scheme_mz_need_space(jitter, 3);
|
||||
generate_vector_op(jitter, 0, 0, base_offset, 0, unsafe,
|
||||
0, 0, can_chaperone, for_struct, for_fx, 0,
|
||||
scheme_jit_is_fixnum(app->rand2), 0,
|
||||
dest);
|
||||
CHECK_LIMIT();
|
||||
} else if (which == 3) {
|
||||
/* flvector-ref is relatively simple and worth inlining */
|
||||
generate_vector_op(jitter, 0, 0, base_offset, 1, unsafe,
|
||||
unbox, 0, can_chaperone, for_struct, for_fx, 0,
|
||||
scheme_jit_is_fixnum(app->rand2), 0,
|
||||
dest);
|
||||
CHECK_LIMIT();
|
||||
} else if (which == 1) {
|
||||
|
@ -2812,12 +2816,14 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i
|
|||
if (can_chaperone) scheme_mz_need_space(jitter, 3);
|
||||
generate_vector_op(jitter, 0, 1, base_offset, 0, unsafe,
|
||||
0, 0, can_chaperone, for_struct, for_fx, 0,
|
||||
scheme_jit_is_fixnum(app->rand2), 0,
|
||||
dest);
|
||||
CHECK_LIMIT();
|
||||
} else if (which == 3) {
|
||||
/* flvector-ref is relatively simple and worth inlining */
|
||||
generate_vector_op(jitter, 0, 1, base_offset, 1, unsafe,
|
||||
unbox, 0, can_chaperone, for_struct, for_fx, 0,
|
||||
scheme_jit_is_fixnum(app->rand2), 0,
|
||||
dest);
|
||||
CHECK_LIMIT();
|
||||
} else if (which == 1) {
|
||||
|
@ -3455,6 +3461,8 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int
|
|||
} else if (IS_NAMED_PRIM(rator, "fxvector-set!")) {
|
||||
which = 0;
|
||||
for_fx = 1;
|
||||
if (scheme_jit_is_fixnum(app->args[3]))
|
||||
for_fx = 2;
|
||||
} else if (IS_NAMED_PRIM(rator, "unsafe-vector*-set!")) {
|
||||
which = 0;
|
||||
unsafe = 1;
|
||||
|
@ -3464,6 +3472,8 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int
|
|||
unsafe = 1;
|
||||
can_chaperone = 0;
|
||||
for_fx = 1;
|
||||
if (scheme_jit_is_fixnum(app->args[3]))
|
||||
for_fx = 2;
|
||||
} else if (IS_NAMED_PRIM(rator, "unsafe-vector-set!")) {
|
||||
which = 0;
|
||||
unsafe = 1;
|
||||
|
@ -3631,13 +3641,17 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int
|
|||
if (can_chaperone) scheme_mz_need_space(jitter, 3);
|
||||
generate_vector_op(jitter, 1, 0, base_offset, 0, unsafe,
|
||||
flonum_arg, result_ignored, can_chaperone,
|
||||
for_struct, for_fx, check_mutable, dest);
|
||||
for_struct, for_fx, check_mutable,
|
||||
scheme_jit_is_fixnum(app->args[2]), for_fx > 1,
|
||||
dest);
|
||||
CHECK_LIMIT();
|
||||
} else if (which == 3) {
|
||||
/* flvector-set! is relatively simple and worth inlining */
|
||||
generate_vector_op(jitter, 1, 0, base_offset, 1, unsafe,
|
||||
flonum_arg, result_ignored, can_chaperone,
|
||||
for_struct, for_fx, 0, dest);
|
||||
for_struct, for_fx, 0,
|
||||
scheme_jit_is_fixnum(app->args[2]), for_fx > 1,
|
||||
dest);
|
||||
CHECK_LIMIT();
|
||||
} else if ((which == 4) || (which == 5)) {
|
||||
/* unsafe-{s,u}16vector-set! */
|
||||
|
@ -3700,7 +3714,9 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int
|
|||
if (can_chaperone) scheme_mz_need_space(jitter, 3);
|
||||
generate_vector_op(jitter, 1, 1, base_offset, 0, unsafe,
|
||||
flonum_arg, result_ignored, can_chaperone,
|
||||
for_struct, for_fx, check_mutable, dest);
|
||||
for_struct, for_fx, check_mutable,
|
||||
scheme_jit_is_fixnum(app->args[2]), for_fx > 1,
|
||||
dest);
|
||||
CHECK_LIMIT();
|
||||
} else if ((which == 4) || (which == 5)) {
|
||||
/* unsafe-{s,u}16vector-set! */
|
||||
|
@ -3718,7 +3734,9 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int
|
|||
/* flvector-set! is relatively simple and worth inlining */
|
||||
generate_vector_op(jitter, 1, 1, base_offset, 1, unsafe,
|
||||
flonum_arg, result_ignored, can_chaperone,
|
||||
for_struct, for_fx, 0, dest);
|
||||
for_struct, for_fx, 0,
|
||||
scheme_jit_is_fixnum(app->args[2]), for_fx > 1,
|
||||
dest);
|
||||
CHECK_LIMIT();
|
||||
} else if (which == 1) {
|
||||
if (unsafe) {
|
||||
|
|
|
@ -2046,6 +2046,7 @@ static int produces_local_type(Scheme_Object *rator, int argc)
|
|||
}
|
||||
|
||||
int scheme_expr_produces_local_type(Scheme_Object *expr)
|
||||
/* can be called by the JIT */
|
||||
{
|
||||
while (1) {
|
||||
switch (SCHEME_TYPE(expr)) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user