From cab8e5e0e2c1397dbcd3ea02e464bbb832360681 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 25 Jul 2011 10:53:23 -0400 Subject: [PATCH] JIT tweaks for `unsafe-{s,u}16vector-set!' by making better use of the code that's in place for other similar operations --- src/racket/src/jit.c | 18 ++++++ src/racket/src/jit.h | 1 + src/racket/src/jitinline.c | 111 +++++++++++++------------------------ 3 files changed, 59 insertions(+), 71 deletions(-) diff --git a/src/racket/src/jit.c b/src/racket/src/jit.c index 6adff06cae..48dc0ee25e 100644 --- a/src/racket/src/jit.c +++ b/src/racket/src/jit.c @@ -830,6 +830,24 @@ int scheme_is_relatively_constant_and_avoids_r1(Scheme_Object *obj, Scheme_Objec return scheme_is_relatively_constant_and_avoids_r1_maybe_fp(obj, wrt, 0); } +int scheme_needs_only_target_register(Scheme_Object *obj, int and_can_reorder) +{ + Scheme_Type t; + + if (scheme_is_constant_and_avoids_r1(obj)) + return 1; + + t = SCHEME_TYPE(obj); + if (SAME_TYPE(t, scheme_local_type)) { + if (and_can_reorder && SCHEME_GET_LOCAL_FLAGS(obj)) + return 0; + if (SCHEME_GET_LOCAL_FLAGS(obj) == SCHEME_LOCAL_FLONUM) + return 0; + return 1; + } else + return (t >= _scheme_compiled_values_types_); +} + /*========================================================================*/ /* branch info */ /*========================================================================*/ diff --git a/src/racket/src/jit.h b/src/racket/src/jit.h index deb1b20b4d..a0c8162898 100644 --- a/src/racket/src/jit.h +++ b/src/racket/src/jit.h @@ -1247,6 +1247,7 @@ int scheme_is_constant_and_avoids_r1(Scheme_Object *obj); int scheme_is_relatively_constant_and_avoids_r1_maybe_fp(Scheme_Object *obj, Scheme_Object *wrt, int fp_ok); int scheme_is_relatively_constant_and_avoids_r1(Scheme_Object *obj, Scheme_Object *wrt); +int scheme_needs_only_target_register(Scheme_Object *obj, int and_can_reorder); int scheme_is_noncm(Scheme_Object *a, mz_jit_state *jitter, int depth, int stack_start); int scheme_is_simple(Scheme_Object *obj, int depth, int just_markless, mz_jit_state *jitter, int stack_start); #define INIT_SIMPLE_DEPTH 10 diff --git a/src/racket/src/jitinline.c b/src/racket/src/jitinline.c index 2b2d81b596..f9d9f5db48 100644 --- a/src/racket/src/jitinline.c +++ b/src/racket/src/jitinline.c @@ -1377,54 +1377,6 @@ static int generate_two_args(Scheme_Object *rand1, Scheme_Object *rand2, mz_jit_ return direction; } -static int generate_three_args(Scheme_App_Rec *app, mz_jit_state *jitter) -/* de-sync's rs. - Puts arguments in R0, R1, and R2. */ -{ - int c1, c2; - - c1 = scheme_is_constant_and_avoids_r1(app->args[1]); - c2 = scheme_is_constant_and_avoids_r1(app->args[2]); - - if (c1 && c2) { - /* we expect this to be a common case for `vector-set!'-like operations, - where the vector and index are immediate and the value is computed */ - mz_runstack_skipped(jitter, 2); - mz_rs_dec(1); /* no sync */ - CHECK_RUNSTACK_OVERFLOW(); - mz_runstack_pushed(jitter, 1); - - scheme_generate(app->args[3], jitter, 0, 0, 0, JIT_R0, NULL); - CHECK_LIMIT(); - - mz_rs_str(JIT_R0); - - scheme_generate(app->args[2], jitter, 0, 0, 0, JIT_R1, NULL); - CHECK_LIMIT(); - scheme_generate(app->args[1], jitter, 0, 0, 0, JIT_R0, NULL); - CHECK_LIMIT(); - - mz_rs_ldr(JIT_R2); /* no sync */ - mz_rs_inc(1); - mz_runstack_popped(jitter, 1); - mz_runstack_unskipped(jitter, 2); - CHECK_LIMIT(); - } else { - scheme_generate_app(app, NULL, 3, jitter, 0, 0, 2); - CHECK_LIMIT(); - - mz_rs_ldxi(JIT_R2, 2); - mz_rs_ldr(JIT_R0); - mz_rs_ldxi(JIT_R1, 1); - - mz_rs_inc(3); /* no sync */ - mz_runstack_popped(jitter, 3); - CHECK_LIMIT(); - } - - return 1; -} - static int generate_binary_char(mz_jit_state *jitter, Scheme_App3_Rec *app, Branch_Info *for_branch, int branch_short) /* de-sync'd ok */ @@ -2814,7 +2766,9 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int || IS_NAMED_PRIM(rator, "string-set!") || IS_NAMED_PRIM(rator, "unsafe-string-set!") || IS_NAMED_PRIM(rator, "bytes-set!") - || IS_NAMED_PRIM(rator, "unsafe-bytes-set!")) { + || IS_NAMED_PRIM(rator, "unsafe-bytes-set!") + || IS_NAMED_PRIM(rator, "unsafe-s16vector-set!") + || IS_NAMED_PRIM(rator, "unsafe-u16vector-set!")) { int simple, constval, can_delay_vec, can_delay_index; int which, unsafe = 0, base_offset = ((int)&SCHEME_VEC_ELS(0x0)); int pushed, flonum_arg; @@ -2857,9 +2811,19 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int else if (IS_NAMED_PRIM(rator, "unsafe-string-set!")) { which = 1; unsafe = 1; + can_chaperone = 0; } else if (IS_NAMED_PRIM(rator, "unsafe-bytes-set!")) { which = 2; unsafe = 1; + can_chaperone = 0; + } else if (IS_NAMED_PRIM(rator, "unsafe-s16vector-set!")) { + which = 4; + unsafe = 1; + can_chaperone = 0; + } else if (IS_NAMED_PRIM(rator, "unsafe-u16vector-set!")) { + which = 5; + unsafe = 1; + can_chaperone = 0; } else which = 2; @@ -3000,6 +2964,19 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int flonum_arg, result_ignored, can_chaperone, for_struct, for_fx, 0); CHECK_LIMIT(); + } else if ((which == 4) || (which == 5)) { + /* unsafe-{s,u}16vector-set! */ + jit_ldxi_p(JIT_R0, JIT_R0, (intptr_t)&(((Scheme_Structure *)0x0)->slots[0])); + jit_ldxi_p(JIT_R0, JIT_R0, (intptr_t)&SCHEME_CPTR_VAL(0x0)); + jit_subi_l(JIT_R1, JIT_R1, 1); + jit_rshi_ul(JIT_R2, JIT_R2, 1); + if (which == 5) + jit_stxr_us(JIT_R1, JIT_R0, JIT_R2); + else + jit_stxr_s(JIT_R1, JIT_R0, JIT_R2); + CHECK_LIMIT(); + if (!result_ignored) + (void)jit_movi_p(JIT_R0, scheme_void); } else if (which == 1) { if (unsafe) { jit_rshi_ul(JIT_R1, JIT_R1, 1); @@ -3036,6 +3013,8 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int offset = base_offset + (offset * sizeof(double)); else if (which == 1) offset = offset << LOG_MZCHAR_SIZE; + else if ((which == 4) || (which == 5)) + offset *= 2; jit_movi_l(JIT_V1, offset); if (!which) { /* vector-set! is relatively simple and worth inlining */ @@ -3044,6 +3023,18 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int flonum_arg, result_ignored, can_chaperone, for_struct, for_fx, check_mutable); CHECK_LIMIT(); + } else if ((which == 4) || (which == 5)) { + /* unsafe-{s,u}16vector-set! */ + jit_ldxi_p(JIT_R0, JIT_R0, (intptr_t)&(((Scheme_Structure *)0x0)->slots[0])); + jit_ldxi_p(JIT_R0, JIT_R0, (intptr_t)&SCHEME_CPTR_VAL(0x0)); + jit_rshi_ul(JIT_R2, JIT_R2, 1); + if (which == 5) + jit_stxi_us(offset, JIT_R0, JIT_R2); + else + jit_stxi_s(offset, JIT_R0, JIT_R2); + CHECK_LIMIT(); + if (!result_ignored) + (void)jit_movi_p(JIT_R0, scheme_void); } else if (which == 3) { /* flvector-set! is relatively simple and worth inlining */ generate_vector_op(jitter, 1, 1, base_offset, 1, unsafe, @@ -3139,28 +3130,6 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int jit_stxr_d_fppop(JIT_R1, JIT_R0, JIT_FPR0); CHECK_LIMIT(); - if (!result_ignored) - (void)jit_movi_p(JIT_R0, scheme_void); - - return 1; - } else if (IS_NAMED_PRIM(rator, "unsafe-s16vector-set!") - || IS_NAMED_PRIM(rator, "unsafe-u16vector-set!")) { - int is_u; - is_u = IS_NAMED_PRIM(rator, "unsafe-u16vector-set!"); - - generate_three_args(app, jitter); - CHECK_LIMIT(); - - jit_ldxi_p(JIT_R0, JIT_R0, (intptr_t)&(((Scheme_Structure *)0x0)->slots[0])); - jit_ldxi_p(JIT_R0, JIT_R0, (intptr_t)&SCHEME_CPTR_VAL(0x0)); - jit_subi_l(JIT_R1, JIT_R1, 1); - jit_rshi_ul(JIT_R2, JIT_R2, 1); - if (is_u) - jit_stxr_us(JIT_R1, JIT_R0, JIT_R2); - else - jit_stxr_s(JIT_R1, JIT_R0, JIT_R2); - CHECK_LIMIT(); - if (!result_ignored) (void)jit_movi_p(JIT_R0, scheme_void);