From cf300b91b91d505a4b970d74cae6d06e833b98d7 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 24 Aug 2010 10:08:20 -0600 Subject: [PATCH] JIT-inline `even?' and `odd?' on fixnums --- collects/tests/racket/optimize.rktl | 8 ++++++++ src/racket/src/jit.c | 15 ++++++++++++++- src/racket/src/number.c | 18 ++++++++---------- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/collects/tests/racket/optimize.rktl b/collects/tests/racket/optimize.rktl index 2949efa7e8..80d01e9b6b 100644 --- a/collects/tests/racket/optimize.rktl +++ b/collects/tests/racket/optimize.rktl @@ -173,6 +173,14 @@ (un #f 'negative? 1) (un #t 'negative? -1) + (un #t 'even? 10) + (un #f 'even? 11) + (un #t 'even? -10) + + (un #f 'odd? 10) + (un #t 'odd? 11) + (un #f 'odd? -10) + (un #t 'real? 1) (un #t 'real? (expt 2 100)) (un #t 'real? 1.0) diff --git a/src/racket/src/jit.c b/src/racket/src/jit.c index bed4cac536..b99ba0e380 100644 --- a/src/racket/src/jit.c +++ b/src/racket/src/jit.c @@ -4418,7 +4418,7 @@ static int can_fast_double(int arith, int cmp, int two_args) return 1; #endif #ifdef INLINE_FP_COMP - if (!arith + if ((!arith && (cmp != 4) && (cmp != -4)) || ((arith == 9) /* min */ && two_args) || ((arith == 10) /* max */ && two_args)) return 1; @@ -4920,6 +4920,7 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj cmp = +/-1 -> >=/<= cmp = +/-2 -> >/< or positive/negative? cmp = 3 -> bitwise-bit-test? + cmp = +/-4 -> even?/odd? If rand is NULL, then we're generating part of the fast path for an nary arithmatic over a binary operator; the first argument is already in R0 (fixnum or min/max) or a floating-point register @@ -5752,6 +5753,9 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj } switch (cmp) { + case -4: + ref3 = jit_bmci_l(jit_forward(), JIT_R0, 0x2); + break; case -3: if (rand2) { if (!unsafe_fx || overflow_refslow) { @@ -5820,6 +5824,9 @@ static int generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj ref3 = jit_bmci_l(jit_forward(), JIT_R0, 1 << (v+1)); } break; + case 4: + ref3 = jit_bmsi_l(jit_forward(), JIT_R0, 0x2); + break; } } } else { @@ -6452,6 +6459,12 @@ static int generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in } else if (IS_NAMED_PRIM(rator, "positive?")) { generate_arith(jitter, rator, app->rand, NULL, 1, 0, 2, 0, for_branch, branch_short, 0, 0, NULL); return 1; + } else if (IS_NAMED_PRIM(rator, "even?")) { + generate_arith(jitter, rator, app->rand, NULL, 1, 0, 4, 0, for_branch, branch_short, 0, 0, NULL); + return 1; + } else if (IS_NAMED_PRIM(rator, "odd?")) { + generate_arith(jitter, rator, app->rand, NULL, 1, 0, -4, 0, for_branch, branch_short, 0, 0, NULL); + return 1; } else if (IS_NAMED_PRIM(rator, "exact-nonnegative-integer?") || IS_NAMED_PRIM(rator, "exact-positive-integer?")) { GC_CAN_IGNORE jit_insn *ref, *ref2, *ref3, *ref4; diff --git a/src/racket/src/number.c b/src/racket/src/number.c index 1227b205a7..a1196bde8d 100644 --- a/src/racket/src/number.c +++ b/src/racket/src/number.c @@ -338,16 +338,14 @@ scheme_init_number (Scheme_Env *env) "inexact?", 1, 1, 1), env); - scheme_add_global_constant("odd?", - scheme_make_folding_prim(scheme_odd_p, - "odd?", - 1, 1, 1), - env); - scheme_add_global_constant("even?", - scheme_make_folding_prim(even_p, - "even?", - 1, 1, 1), - env); + + p = scheme_make_folding_prim(scheme_odd_p, "odd?", 1, 1, 1); + SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNARY_INLINED; + scheme_add_global_constant("odd?", p, env); + + p = scheme_make_folding_prim(even_p, "even?", 1, 1, 1); + SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_UNARY_INLINED; + scheme_add_global_constant("even?", p, env); p = scheme_make_folding_prim(scheme_bitwise_and, "bitwise-and", 0, -1, 1); SCHEME_PRIM_PROC_FLAGS(p) |= (SCHEME_PRIM_IS_BINARY_INLINED