First stab at optimizing bounds checking.

This commit is contained in:
Vincent St-Amour 2011-07-06 14:01:20 -04:00
parent 63ae1cabc4
commit 979545a90f
2 changed files with 52 additions and 6 deletions

View File

@ -0,0 +1,32 @@
#;
(
TR opt: bounds-check.rkt 16:2 (vector-ref v i) -- vector access splitting
TR opt: bounds-check.rkt 19:2 (vector-set! v i n) -- vector access splitting
TR opt: bounds-check.rkt 22:2 (vector-ref v i) -- vector access splitting
TR opt: bounds-check.rkt 25:2 (vector-set! v i n) -- vector access splitting
3
4
5
)
#lang typed/racket
(: f (All (X) ((Vectorof X) Fixnum -> X)))
(define (f v i)
(vector-ref v i))
(: g (All (X) ((Vectorof X) Fixnum X -> Void)))
(define (g v i n)
(vector-set! v i n))
(: h (All (X) ((Vectorof X) Index -> X)))
(define (h v i)
(vector-ref v i))
(: a (All (X) ((Vectorof X) Index X -> Void)))
(define (a v i n)
(vector-set! v i n))
(define: v : (Vectorof Integer) (vector 1 2 3 4))
(displayln (f v 2))
(g v 2 4)
(displayln (h v 2))
(a v 2 5)
(displayln (f v 2))

View File

@ -5,8 +5,8 @@
(for-template scheme/base racket/flonum scheme/unsafe/ops)
"../utils/utils.rkt"
(rep type-rep)
(types type-table utils)
(optimizer utils logging))
(types type-table utils numeric-tower)
(optimizer utils logging fixnum))
(provide vector-opt-expr)
@ -17,7 +17,7 @@
(pattern (~literal vector-ref) #:with unsafe #'unsafe-vector-ref)
(pattern (~literal vector-set!) #:with unsafe #'unsafe-vector-set!))
(define-syntax-class vector-expr
(define-syntax-class known-length-vector-expr
#:commit
(pattern e:expr
#:when (match (type-of #'e)
@ -31,7 +31,7 @@
(pattern (#%plain-app (~and op (~or (~literal vector-length)
(~literal unsafe-vector-length)
(~literal unsafe-vector*-length)))
v:vector-expr)
v:known-length-vector-expr)
#:with opt
(begin (log-optimization "known-length vector-length" #'op)
(match (type-of #'v)
@ -51,7 +51,7 @@
#`(unsafe-flvector-length #,((optimize) #'v))))
;; we can optimize vector ref and set! on vectors of known length if we know
;; the index is within bounds (for now, literal or singleton type)
(pattern (#%plain-app op:vector-op v:vector-expr i:expr new:expr ...)
(pattern (#%plain-app op:vector-op v:known-length-vector-expr i:expr new:expr ...)
#:when (let ((len (match (type-of #'v)
[(tc-result1: (HeterogenousVector: es)) (length es)]
[_ 0]))
@ -63,4 +63,18 @@
#:with opt
(begin (log-optimization "vector" #'op)
#`(op.unsafe v.opt #,((optimize) #'i)
#,@(syntax-map (optimize) #'(new ...))))))
#,@(syntax-map (optimize) #'(new ...)))))
;; we can do the bounds checking separately, to eliminate some of the checks
(pattern (#%plain-app op:vector-op v:expr i:fixnum-expr new:expr ...)
#:with opt
(begin (log-optimization "vector access splitting" this-syntax)
#`(let ([new-i #,((optimize) #'i)]
[new-v #,((optimize) #'v)])
(if #,(let ([one-sided #'(unsafe-fx< new-i (unsafe-vector*-length v))])
(if (subtypeof? #'i -NonNegFixnum)
;; we know it's nonnegative, one-sided check
one-sided
#`(and (unsafe-fx>= new-i 0)
#,one-sided)))
(op.unsafe new-v new-i #,@(syntax-map (optimize) #'(new ...)))
(op new-v new-i #,@(syntax-map (optimize) #'(new ...))))))))