improved JIT inlining of 'list'

svn: r12428
This commit is contained in:
Matthew Flatt 2008-11-13 16:42:15 +00:00
parent a93b36c953
commit bac4053c37
2 changed files with 75 additions and 18 deletions

View File

@ -300,14 +300,17 @@
exact-positive-integer? exact-positive-integer?
car cdr caar cadr cdar cddr car cdr caar cadr cdar cddr
mcar mcdr unbox vector-length syntax-e mcar mcdr unbox vector-length syntax-e
add1 sub1 - abs bitwise-not))] add1 sub1 - abs bitwise-not
list vector box))]
[(3) (memq (car a) '(eq? = <= < >= > [(3) (memq (car a) '(eq? = <= < >= >
bitwise-bit-set? char=? bitwise-bit-set? char=?
+ - * / min max bitwise-and bitwise-ior + - * / min max bitwise-and bitwise-ior
arithmetic-shift vector-ref string-ref bytes-ref arithmetic-shift vector-ref string-ref bytes-ref
set-mcar! set-mcdr! cons mcons))] set-mcar! set-mcdr! cons mcons
[(4) (memq (car a) '(vector-set! string-set! bytes-set!))] list vector))]
[else #f])) [(4) (memq (car a) '(vector-set! string-set! bytes-set!
list vector))]
[else (memq (car a) '(list vector))]))
(cons '#%in a) (cons '#%in a)
a)) a))

View File

@ -1220,6 +1220,10 @@ static void *malloc_double(void)
# define cons scheme_make_pair # define cons scheme_make_pair
#endif #endif
#ifdef CAN_INLINE_ALLOC
static void *make_list_code;
# define make_list make_list_code
#else
static Scheme_Object *make_list(long n) static Scheme_Object *make_list(long n)
{ {
GC_CAN_IGNORE Scheme_Object *l = scheme_null; GC_CAN_IGNORE Scheme_Object *l = scheme_null;
@ -1231,6 +1235,7 @@ static Scheme_Object *make_list(long n)
return l; return l;
} }
#endif
#if !defined(CAN_INLINE_ALLOC) #if !defined(CAN_INLINE_ALLOC)
static Scheme_Object *make_vector(long n) static Scheme_Object *make_vector(long n)
@ -3680,7 +3685,7 @@ static int generate_inlined_struct_op(int kind, mz_jit_state *jitter,
return 1; return 1;
} }
static int generate_cons_alloc(mz_jit_state *jitter); static int generate_cons_alloc(mz_jit_state *jitter, int rev);
static int generate_vector_alloc(mz_jit_state *jitter, Scheme_Object *rator, static int generate_vector_alloc(mz_jit_state *jitter, Scheme_Object *rator,
Scheme_App_Rec *app, Scheme_App2_Rec *app2, Scheme_App3_Rec *app3); Scheme_App_Rec *app, Scheme_App2_Rec *app2, Scheme_App3_Rec *app3);
@ -4043,7 +4048,7 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in
CHECK_LIMIT(); CHECK_LIMIT();
mz_runstack_unskipped(jitter, 1); mz_runstack_unskipped(jitter, 1);
jit_movi_p(JIT_R1, &scheme_null); jit_movi_p(JIT_R1, &scheme_null);
return generate_cons_alloc(jitter); return generate_cons_alloc(jitter, 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);
@ -4519,7 +4524,7 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i
generate_two_args(app->rand1, app->rand2, jitter, 1); generate_two_args(app->rand1, app->rand2, jitter, 1);
CHECK_LIMIT(); CHECK_LIMIT();
return generate_cons_alloc(jitter); return generate_cons_alloc(jitter, 0);
} else if (IS_NAMED_PRIM(rator, "mcons")) { } else if (IS_NAMED_PRIM(rator, "mcons")) {
LOG_IT(("inlined mcons\n")); LOG_IT(("inlined mcons\n"));
@ -4555,20 +4560,18 @@ static int generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i
CHECK_RUNSTACK_OVERFLOW(); CHECK_RUNSTACK_OVERFLOW();
mz_runstack_pushed(jitter, 1); mz_runstack_pushed(jitter, 1);
jit_str_p(JIT_RUNSTACK, JIT_R0); jit_str_p(JIT_RUNSTACK, JIT_R0);
jit_movr_p(JIT_R0, JIT_R1); jit_movi_p(JIT_R0, &scheme_null);
jit_movi_p(JIT_R1, &scheme_null);
CHECK_LIMIT(); CHECK_LIMIT();
generate_cons_alloc(jitter); generate_cons_alloc(jitter, 1);
CHECK_LIMIT(); CHECK_LIMIT();
jit_movr_p(JIT_R1, JIT_R0); jit_ldr_p(JIT_R1, JIT_RUNSTACK);
jit_ldr_p(JIT_R0, JIT_RUNSTACK);
jit_addi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); jit_addi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1));
mz_runstack_popped(jitter, 1); mz_runstack_popped(jitter, 1);
CHECK_LIMIT(); CHECK_LIMIT();
return generate_cons_alloc(jitter); return generate_cons_alloc(jitter, 1);
} else if (IS_NAMED_PRIM(rator, "vector-immutable") } else if (IS_NAMED_PRIM(rator, "vector-immutable")
|| IS_NAMED_PRIM(rator, "vector")) { || IS_NAMED_PRIM(rator, "vector")) {
return generate_vector_alloc(jitter, rator, NULL, NULL, app); return generate_vector_alloc(jitter, rator, NULL, NULL, app);
@ -4717,7 +4720,10 @@ static int generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int
generate_app(app, NULL, c, jitter, 0, 0, 1); generate_app(app, NULL, c, jitter, 0, 0, 1);
CHECK_LIMIT(); CHECK_LIMIT();
#ifndef CAN_INLINE_ALLOC
/* make_list is make_list_code, which uses MZ_RUNSTACK directly */
JIT_UPDATE_THREAD_RSPTR_IF_NEEDED(); JIT_UPDATE_THREAD_RSPTR_IF_NEEDED();
#endif
jit_movi_l(JIT_R0, c); jit_movi_l(JIT_R0, c);
mz_prepare(1); mz_prepare(1);
jit_pusharg_l(JIT_R0); jit_pusharg_l(JIT_R0);
@ -4743,7 +4749,7 @@ static int generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int
return 0; return 0;
} }
static int generate_cons_alloc(mz_jit_state *jitter) static int generate_cons_alloc(mz_jit_state *jitter, int rev)
{ {
/* Args should be in R0 (car) and R1 (cdr) */ /* Args should be in R0 (car) and R1 (cdr) */
@ -4752,15 +4758,25 @@ static int generate_cons_alloc(mz_jit_state *jitter)
inline_alloc(jitter, sizeof(Scheme_Simple_Object), scheme_pair_type, 0, 1, 0); inline_alloc(jitter, sizeof(Scheme_Simple_Object), scheme_pair_type, 0, 1, 0);
CHECK_LIMIT(); CHECK_LIMIT();
if (rev) {
jit_stxi_p((long)&SCHEME_CAR(0x0) + sizeof(long), JIT_V1, JIT_R1);
jit_stxi_p((long)&SCHEME_CDR(0x0) + sizeof(long), JIT_V1, JIT_R0);
} else {
jit_stxi_p((long)&SCHEME_CAR(0x0) + sizeof(long), JIT_V1, JIT_R0); jit_stxi_p((long)&SCHEME_CAR(0x0) + sizeof(long), JIT_V1, JIT_R0);
jit_stxi_p((long)&SCHEME_CDR(0x0) + sizeof(long), JIT_V1, JIT_R1); jit_stxi_p((long)&SCHEME_CDR(0x0) + sizeof(long), JIT_V1, JIT_R1);
}
jit_addi_p(JIT_R0, JIT_V1, sizeof(long)); jit_addi_p(JIT_R0, JIT_V1, sizeof(long));
#else #else
/* Non-inlined */ /* Non-inlined */
JIT_UPDATE_THREAD_RSPTR_IF_NEEDED(); JIT_UPDATE_THREAD_RSPTR_IF_NEEDED();
mz_prepare(2); mz_prepare(2);
if (rev) {
jit_pusharg_p(JIT_R0);
jit_pusharg_p(JIT_R1);
} else {
jit_pusharg_p(JIT_R1); jit_pusharg_p(JIT_R1);
jit_pusharg_p(JIT_R0); jit_pusharg_p(JIT_R0);
}
(void)mz_finish(scheme_make_pair); (void)mz_finish(scheme_make_pair);
jit_retval(JIT_R0); jit_retval(JIT_R0);
#endif #endif
@ -7220,6 +7236,44 @@ static int do_generate_common(mz_jit_state *jitter, void *_data)
} }
#endif #endif
#ifdef CAN_INLINE_ALLOC
/* *** make_list_code *** */
{
jit_insn *ref, *refnext;
make_list_code = jit_get_ip().ptr;
jit_prolog(1);
in = jit_arg_p();
jit_getarg_p(JIT_R2, in); /* count */
mz_push_locals();
jit_lshi_l(JIT_R2, JIT_R2, JIT_LOG_WORD_SIZE);
jit_movi_p(JIT_R0, &scheme_null);
__START_SHORT_JUMPS__(1);
refnext = _jit.x.pc;
ref = jit_beqi_l(jit_forward(), JIT_R2, 0);
__END_SHORT_JUMPS__(1);
CHECK_LIMIT();
jit_subi_l(JIT_R2, JIT_R2, JIT_WORD_SIZE);
jit_ldxr_p(JIT_R1, JIT_RUNSTACK, JIT_R2);
mz_set_local_p(JIT_R2, JIT_LOCAL2);
generate_cons_alloc(jitter, 1);
CHECK_LIMIT();
mz_get_local_p(JIT_R2, JIT_LOCAL2);
__START_SHORT_JUMPS__(1);
(void)jit_jmpi(refnext);
mz_patch_branch(ref);
__END_SHORT_JUMPS__(1);
mz_pop_locals();
jit_ret();
}
#endif
return 1; return 1;
} }