performance tweaks for `for/{fx,fl,extfl}vector'

Also, provide a better error message when the body produces a
non-{fix,flo,extflo}num.
This commit is contained in:
Matthew Flatt 2013-04-10 17:22:58 -06:00
parent 37c55967b0
commit d4fa2766c2
9 changed files with 72 additions and 8 deletions

View File

@ -138,6 +138,7 @@
(define-vector-wraps "bit-vector" (define-vector-wraps "bit-vector"
"boolean?" boolean?
bit-vector? bit-vector-length bit-vector-ref bit-vector-set! make-bit-vector bit-vector? bit-vector-length bit-vector-ref bit-vector-set! make-bit-vector
unsafe-bit-vector-ref bit-vector-set! bit-vector-length unsafe-bit-vector-ref bit-vector-set! bit-vector-length
in-bit-vector* in-bit-vector*

View File

@ -11,6 +11,7 @@
extflvector-copy) extflvector-copy)
(define-vector-wraps "extflvector" (define-vector-wraps "extflvector"
"extflonum?" extflonum?
extflvector? extflvector-length extflvector-ref extflvector-set! make-extflvector extflvector? extflvector-length extflvector-ref extflvector-set! make-extflvector
unsafe-extflvector-ref unsafe-extflvector-set! unsafe-extflvector-length unsafe-extflvector-ref unsafe-extflvector-set! unsafe-extflvector-length
in-extflvector* in-extflvector*

View File

@ -20,6 +20,7 @@
in-fxvector for/fxvector for*/fxvector) in-fxvector for/fxvector for*/fxvector)
(define-vector-wraps "fxvector" (define-vector-wraps "fxvector"
"fixnum?" fixnum?
fxvector? fxvector-length fxvector-ref fxvector-set! make-fxvector fxvector? fxvector-length fxvector-ref fxvector-set! make-fxvector
unsafe-fxvector-ref unsafe-fxvector-set! unsafe-fxvector-length unsafe-fxvector-ref unsafe-fxvector-set! unsafe-fxvector-length
in-fxvector* in-fxvector*

View File

@ -19,6 +19,7 @@
in-flvector for/flvector for*/flvector) in-flvector for/flvector for*/flvector)
(define-vector-wraps "flvector" (define-vector-wraps "flvector"
"flonum?" flonum?
flvector? flvector-length flvector-ref flvector-set! make-flvector flvector? flvector-length flvector-ref flvector-set! make-flvector
unsafe-flvector-ref unsafe-flvector-set! unsafe-flvector-length unsafe-flvector-ref unsafe-flvector-set! unsafe-flvector-length
in-flvector* in-flvector*

View File

@ -1497,10 +1497,10 @@
[i 0]) [i 0])
(for-clause ...) (for-clause ...)
middle-body ... middle-body ...
(let ([new-vec (if (eq? i (unsafe-vector-length vec)) (let ([new-vec (if (eq? i (unsafe-vector*-length vec))
(grow-vector vec) (grow-vector vec)
vec)]) vec)])
(unsafe-vector-set! new-vec i (let () last-body ...)) (unsafe-vector*-set! new-vec i (let () last-body ...))
(values new-vec (unsafe-fx+ i 1))))]) (values new-vec (unsafe-fx+ i 1))))])
(shrink-vector vec i))))] (shrink-vector vec i))))]
[(_ #:length length-expr #:fill fill-expr (for-clause ...) body ...) [(_ #:length length-expr #:fill fill-expr (for-clause ...) body ...)
@ -1546,8 +1546,8 @@
([i 0]) ([i 0])
(limited-for-clause ...) (limited-for-clause ...)
middle-body ... middle-body ...
(vector-set! v i (let () last-body ...)) (unsafe-vector*-set! v i (let () last-body ...))
(add1 i))) (unsafe-fx+ 1 i)))
v))))] v))))]
[(_ #:length length-expr (for-clause ...) body ...) [(_ #:length length-expr (for-clause ...) body ...)
(for_/vector #'(fv #:length length-expr #:fill 0 (for-clause ...) body ...) (for_/vector #'(fv #:length length-expr #:fill 0 (for-clause ...) body ...)

View File

@ -9,6 +9,7 @@
(define-syntax-rule (define-vector-wraps (define-syntax-rule (define-vector-wraps
fXvector-str fXvector-str
fX?-str fX?
fXvector? fXvector-length fXvector-ref fXvector-set! make-fXvector fXvector? fXvector-length fXvector-ref fXvector-set! make-fXvector
unsafe-fXvector-ref unsafe-fXvector-set! unsafe-fXvector-length unsafe-fXvector-ref unsafe-fXvector-set! unsafe-fXvector-length
in-fXvector* in-fXvector*
@ -50,6 +51,9 @@
(unsafe-fXvector-copy! new-vec 0 vec 0 i) (unsafe-fXvector-copy! new-vec 0 vec 0 i)
new-vec) new-vec)
(define (not-an-fX who v)
(raise-argument-error who fX?-str v))
(define-for-syntax (for_/fXvector stx orig-stx for_/fXvector-stx for_/fold/derived-stx wrap-all?) (define-for-syntax (for_/fXvector stx orig-stx for_/fXvector-stx for_/fold/derived-stx wrap-all?)
(syntax-case stx () (syntax-case stx ()
[(for*/fXvector (for-clause ...) body ...) [(for*/fXvector (for-clause ...) body ...)
@ -67,7 +71,10 @@
(let ([new-vec (if (eq? i (unsafe-fXvector-length vec)) (let ([new-vec (if (eq? i (unsafe-fXvector-length vec))
(grow-fXvector vec) (grow-fXvector vec)
vec)]) vec)])
(fXvector-set! new-vec i (let () last-body ...)) (let ([elem (let () last-body ...)])
(if (fX? elem)
(unsafe-fXvector-set! new-vec i elem)
(not-an-fX 'for*/fXvector elem)))
(values new-vec (unsafe-fx+ i 1))))]) (values new-vec (unsafe-fx+ i 1))))])
(shrink-fXvector vec i))))] (shrink-fXvector vec i))))]
[(for*/fXvector #:length length-expr #:fill fill-expr (for-clause ...) body ...) [(for*/fXvector #:length length-expr #:fill fill-expr (for-clause ...) body ...)
@ -114,8 +121,11 @@
([i 0]) ([i 0])
(limited-for-clause ...) (limited-for-clause ...)
middle-body ... middle-body ...
(fXvector-set! v i (let () last-body ...)) (let ([elem (let () last-body ...)])
(add1 i))) (if (fX? elem)
(unsafe-fXvector-set! v i elem)
(not-an-fX 'for*/vector elem)))
(unsafe-fx+ 1 i)))
v)))))] v)))))]
[(_ #:length length-expr (for-clause ...) body ...) [(_ #:length length-expr (for-clause ...) body ...)
(for_/fXvector #'(fv #:length length-expr #:fill fXzero (for-clause ...) body ...) (for_/fXvector #'(fv #:length length-expr #:fill fXzero (for-clause ...) body ...)

View File

@ -1788,6 +1788,32 @@
(+ p (unsafe-fx- p 1) (- p p) t)) (+ p (unsafe-fx- p 1) (- p p) t))
'ok)))) 'ok))))
;; eliminate unneeded tests:
(test-comp '(lambda (n)
(let ([p (fl+ n n)])
(if (flonum? p)
(fl+ p p)
'bad)))
'(lambda (n)
(let ([p (fl+ n n)])
(fl+ p p))))
(test-comp '(lambda (n)
(let ([p (fx+ n n)])
(if (fixnum? p)
(fx+ p p)
'bad)))
'(lambda (n)
(let ([p (fx+ n n)])
(fx+ p p))))
(test-comp '(lambda (n)
(let ([p (extfl+ n n)])
(if (extflonum? p)
(extfl+ p p)
'bad)))
'(lambda (n)
(let ([p (extfl+ n n)])
(extfl+ p p))))
;; simple cross-module inlining ;; simple cross-module inlining
(test-comp `(module m racket/base (test-comp `(module m racket/base
(require racket/bool) (require racket/bool)

View File

@ -815,7 +815,8 @@ void scheme_init_flfxnum_number(Scheme_Env *env)
flags = SCHEME_PRIM_IS_UNARY_INLINED; flags = SCHEME_PRIM_IS_UNARY_INLINED;
else else
flags = SCHEME_PRIM_SOMETIMES_INLINED; flags = SCHEME_PRIM_SOMETIMES_INLINED;
SCHEME_PRIM_PROC_FLAGS(p) |= scheme_intern_prim_opt_flags(flags); SCHEME_PRIM_PROC_FLAGS(p) |= scheme_intern_prim_opt_flags(flags
| SCHEME_PRIM_PRODUCES_FLONUM);
scheme_add_global_constant("->fl", p, env); scheme_add_global_constant("->fl", p, env);
p = scheme_make_folding_prim(fl_to_integer, "fl->exact-integer", 1, 1, 1); p = scheme_make_folding_prim(fl_to_integer, "fl->exact-integer", 1, 1, 1);

View File

@ -2361,6 +2361,29 @@ static Scheme_Object *finish_optimize_application2(Scheme_App2_Rec *app, Optimiz
info->single_result = -info->single_result; info->single_result = -info->single_result;
} }
/* Check for things like (flonum? x) on an `x' known to have a flonum value. */
if (SCHEME_PRIMP(app->rator)
&& (SCHEME_PRIM_PROC_OPT_FLAGS(app->rator) & SCHEME_PRIM_IS_UNARY_INLINED)
&& SAME_TYPE(SCHEME_TYPE(app->rand), scheme_local_type)) {
int pos = SCHEME_LOCAL_POS(app->rand);
if (!optimize_is_mutated(info, pos)) {
int t;
t = optimize_is_local_type_valued(info, pos);
if (t == SCHEME_LOCAL_TYPE_FLONUM) {
if (IS_NAMED_PRIM(app->rator, "flonum?"))
return scheme_true;
} else if (t == SCHEME_LOCAL_TYPE_FIXNUM) {
if (IS_NAMED_PRIM(app->rator, "fixnum?"))
return scheme_true;
} else if (t == SCHEME_LOCAL_TYPE_EXTFLONUM) {
if (IS_NAMED_PRIM(app->rator, "extflonum?"))
return scheme_true;
}
}
}
/* Check for things like (cXr (cons X Y)): */ /* Check for things like (cXr (cons X Y)): */
if (SCHEME_PRIMP(app->rator) if (SCHEME_PRIMP(app->rator)
&& (SCHEME_PRIM_PROC_OPT_FLAGS(app->rator) & SCHEME_PRIM_IS_UNARY_INLINED)) { && (SCHEME_PRIM_PROC_OPT_FLAGS(app->rator) & SCHEME_PRIM_IS_UNARY_INLINED)) {