Added optimizations for iterating over vectors and strings.
This commit is contained in:
parent
1e550139aa
commit
0b0da84eba
|
@ -0,0 +1,4 @@
|
|||
#lang typed/scheme #:optimize
|
||||
(require racket/unsafe/ops)
|
||||
(for: ((i : Integer #"123"))
|
||||
(display i))
|
|
@ -0,0 +1,4 @@
|
|||
#lang typed/scheme #:optimize
|
||||
(require racket/unsafe/ops)
|
||||
(for: ((i : Char "123"))
|
||||
(display i))
|
|
@ -0,0 +1,4 @@
|
|||
#lang typed/scheme #:optimize
|
||||
(require racket/unsafe/ops)
|
||||
(for: ((i : Integer (vector 1 2 3)))
|
||||
(display i))
|
|
@ -0,0 +1,37 @@
|
|||
#lang racket
|
||||
(require racket/unsafe/ops)
|
||||
;; the following code should be equivalent to the code generated by:
|
||||
;; (for: ((i : Integer (in-bytes #"123")))
|
||||
;; (display i))
|
||||
(let-values (((pos->vals pos-next init pos-cont? val-cont? all-cont?)
|
||||
(let* ((i #"123")
|
||||
(len (bytes-length i)))
|
||||
(values (lambda (x) (bytes-ref i x))
|
||||
(lambda (x) (unsafe-fx+ 1 x))
|
||||
0
|
||||
(lambda (x) (unsafe-fx< x len))
|
||||
(lambda (x) #t)
|
||||
(lambda (x y) #t)))))
|
||||
(void)
|
||||
((letrec-values (((for-loop)
|
||||
(#%plain-lambda
|
||||
(fold-var pos)
|
||||
(if (pos-cont? pos)
|
||||
(let-values (((i) (pos->vals pos)))
|
||||
(if (val-cont? i)
|
||||
(let-values (((fold-var)
|
||||
(let-values (((fold-var)
|
||||
fold-var))
|
||||
(let-values ()
|
||||
(let-values ()
|
||||
(display i))
|
||||
(void)))))
|
||||
(if (all-cont? pos i)
|
||||
(for-loop fold-var (pos-next pos))
|
||||
fold-var))
|
||||
fold-var))
|
||||
fold-var))))
|
||||
for-loop)
|
||||
(void)
|
||||
init))
|
||||
(void)
|
|
@ -0,0 +1,37 @@
|
|||
#lang racket
|
||||
(require racket/unsafe/ops)
|
||||
;; the following code should be equivalent to the code generated by:
|
||||
;; (for: ((i : Char (in-string "123")))
|
||||
;; (display i))
|
||||
(let-values (((pos->vals pos-next init pos-cont? val-cont? all-cont?)
|
||||
(let* ((i "123")
|
||||
(len (string-length i)))
|
||||
(values (lambda (x) (string-ref i x))
|
||||
(lambda (x) (unsafe-fx+ 1 x))
|
||||
0
|
||||
(lambda (x) (unsafe-fx< x len))
|
||||
(lambda (x) #t)
|
||||
(lambda (x y) #t)))))
|
||||
(void)
|
||||
((letrec-values (((for-loop)
|
||||
(#%plain-lambda
|
||||
(fold-var pos)
|
||||
(if (pos-cont? pos)
|
||||
(let-values (((i) (pos->vals pos)))
|
||||
(if (val-cont? i)
|
||||
(let-values (((fold-var)
|
||||
(let-values (((fold-var)
|
||||
fold-var))
|
||||
(let-values ()
|
||||
(let-values ()
|
||||
(display i))
|
||||
(void)))))
|
||||
(if (all-cont? pos i)
|
||||
(for-loop fold-var (pos-next pos))
|
||||
fold-var))
|
||||
fold-var))
|
||||
fold-var))))
|
||||
for-loop)
|
||||
(void)
|
||||
init))
|
||||
(void)
|
|
@ -0,0 +1,37 @@
|
|||
#lang racket
|
||||
(require racket/unsafe/ops)
|
||||
;; the following code should be equivalent to the code generated by:
|
||||
;; (for: ((i : Integer (in-vector '(1 2 3))))
|
||||
;; (display i))
|
||||
(let-values (((pos->vals pos-next init pos-cont? val-cont? all-cont?)
|
||||
(let* ((i (vector 1 2 3))
|
||||
(len (unsafe-vector*-length i)))
|
||||
(values (lambda (x) (unsafe-vector*-ref i x))
|
||||
(lambda (x) (unsafe-fx+ 1 x))
|
||||
0
|
||||
(lambda (x) (unsafe-fx< x len))
|
||||
(lambda (x) #t)
|
||||
(lambda (x y) #t)))))
|
||||
(void)
|
||||
((letrec-values (((for-loop)
|
||||
(#%plain-lambda
|
||||
(fold-var pos)
|
||||
(if (pos-cont? pos)
|
||||
(let-values (((i) (pos->vals pos)))
|
||||
(if (val-cont? i)
|
||||
(let-values (((fold-var)
|
||||
(let-values (((fold-var)
|
||||
fold-var))
|
||||
(let-values ()
|
||||
(let-values ()
|
||||
(display i))
|
||||
(void)))))
|
||||
(if (all-cont? pos i)
|
||||
(for-loop fold-var (pos-next pos))
|
||||
fold-var))
|
||||
fold-var))
|
||||
fold-var))))
|
||||
for-loop)
|
||||
(void)
|
||||
init))
|
||||
(void)
|
|
@ -1,35 +0,0 @@
|
|||
#lang scheme/base
|
||||
|
||||
(require syntax/parse
|
||||
syntax/id-table racket/dict
|
||||
unstable/match scheme/match
|
||||
(for-template scheme/base scheme/unsafe/ops)
|
||||
"../utils/utils.rkt" "../utils/tc-utils.rkt"
|
||||
(rep type-rep)
|
||||
(types abbrev type-table utils subtype)
|
||||
(optimizer utils))
|
||||
|
||||
(provide list-opt-expr)
|
||||
|
||||
|
||||
(define-syntax-class list-expr
|
||||
(pattern e:expr
|
||||
#:when (match (type-of #'e)
|
||||
[(tc-result1: (Listof: _)) #t]
|
||||
[(tc-result1: (List: _)) #t]
|
||||
[_ #f])
|
||||
#:with opt ((optimize) #'e)))
|
||||
|
||||
(define-syntax-class list-opt-expr
|
||||
;; if we're iterating (with the for macros) over something we know is a list,
|
||||
;; we can generate code that would be similar to if in-list had been used
|
||||
(pattern (#%plain-app op:id _ l)
|
||||
#:when (id-from? #'op 'make-sequence 'racket/private/for)
|
||||
#:with l*:list-expr #'l
|
||||
#:with opt
|
||||
(begin (log-optimization "in-list" #'op)
|
||||
#'(let ((i l*.opt))
|
||||
(values unsafe-car unsafe-cdr i
|
||||
(lambda (x) (not (null? x)))
|
||||
(lambda (x) #t)
|
||||
(lambda (x y) #t))))))
|
|
@ -5,7 +5,7 @@
|
|||
(for-template scheme/base scheme/flonum scheme/fixnum scheme/unsafe/ops racket/private/for)
|
||||
"../utils/utils.rkt"
|
||||
(types abbrev type-table utils subtype)
|
||||
(optimizer utils fixnum float inexact-complex vector pair list struct dead-code))
|
||||
(optimizer utils fixnum float inexact-complex vector pair sequence struct dead-code))
|
||||
|
||||
(provide optimize-top)
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
|||
(pattern e:inexact-complex-opt-expr #:with opt #'e.opt)
|
||||
(pattern e:vector-opt-expr #:with opt #'e.opt)
|
||||
(pattern e:pair-opt-expr #:with opt #'e.opt)
|
||||
(pattern e:list-opt-expr #:with opt #'e.opt)
|
||||
(pattern e:sequence-opt-expr #:with opt #'e.opt)
|
||||
(pattern e:struct-opt-expr #:with opt #'e.opt)
|
||||
(pattern e:dead-code-opt-expr #:with opt #'e.opt)
|
||||
|
||||
|
|
94
collects/typed-scheme/optimizer/sequence.rkt
Normal file
94
collects/typed-scheme/optimizer/sequence.rkt
Normal file
|
@ -0,0 +1,94 @@
|
|||
#lang scheme/base
|
||||
|
||||
(require syntax/parse
|
||||
syntax/id-table racket/dict
|
||||
unstable/match scheme/match
|
||||
(for-template scheme/base scheme/unsafe/ops)
|
||||
"../utils/utils.rkt" "../utils/tc-utils.rkt"
|
||||
(rep type-rep)
|
||||
(types abbrev type-table utils subtype)
|
||||
(optimizer utils))
|
||||
|
||||
(provide sequence-opt-expr)
|
||||
|
||||
|
||||
(define-syntax-class list-expr
|
||||
(pattern e:expr
|
||||
#:when (match (type-of #'e)
|
||||
[(tc-result1: (Listof: _)) #t]
|
||||
[(tc-result1: (List: _)) #t]
|
||||
[_ #f])
|
||||
#:with opt ((optimize) #'e)))
|
||||
|
||||
;; unlike other vector optimizations, this works on unknown-length vectors
|
||||
(define-syntax-class vector-expr
|
||||
(pattern e:expr
|
||||
#:when (match (type-of #'e)
|
||||
[(tc-result1: (Vector: _)) #t]
|
||||
[(tc-result1: (HeterogenousVector: _)) #t]
|
||||
[_ #f])
|
||||
#:with opt ((optimize) #'e)))
|
||||
|
||||
(define-syntax-class string-expr
|
||||
(pattern e:expr
|
||||
#:when (isoftype? #'e -String)
|
||||
#:with opt ((optimize) #'e)))
|
||||
(define-syntax-class bytes-expr
|
||||
(pattern e:expr
|
||||
#:when (isoftype? #'e -Bytes)
|
||||
#:with opt ((optimize) #'e)))
|
||||
|
||||
(define-syntax-class sequence-opt-expr
|
||||
;; if we're iterating (with the for macros) over something we know is a list,
|
||||
;; we can generate code that would be similar to if in-list had been used
|
||||
(pattern (#%plain-app op:id _ l)
|
||||
#:when (id-from? #'op 'make-sequence 'racket/private/for)
|
||||
#:with l*:list-expr #'l
|
||||
#:with opt
|
||||
(begin (log-optimization "in-list" #'op)
|
||||
#'(let ((i l*.opt))
|
||||
(values unsafe-car unsafe-cdr i
|
||||
(lambda (x) (not (null? x)))
|
||||
(lambda (x) #t)
|
||||
(lambda (x y) #t)))))
|
||||
;; idem for vectors
|
||||
(pattern (#%plain-app op:id _ v)
|
||||
#:when (id-from? #'op 'make-sequence 'racket/private/for)
|
||||
#:with v*:vector-expr #'v
|
||||
#:with opt
|
||||
(begin (log-optimization "in-vector" #'op)
|
||||
#'(let* ((i v*.opt)
|
||||
(len (unsafe-vector*-length i)))
|
||||
(values (lambda (x) (unsafe-vector*-ref i x))
|
||||
(lambda (x) (unsafe-fx+ 1 x))
|
||||
0
|
||||
(lambda (x) (unsafe-fx< x len))
|
||||
(lambda (x) #t)
|
||||
(lambda (x y) #t)))))
|
||||
;; and (byte) strings
|
||||
(pattern (#%plain-app op:id _ s)
|
||||
#:when (id-from? #'op 'make-sequence 'racket/private/for)
|
||||
#:with s*:string-expr #'s
|
||||
#:with opt
|
||||
(begin (log-optimization "in-string" #'op)
|
||||
#'(let* ((i s*.opt)
|
||||
(len (string-length i)))
|
||||
(values (lambda (x) (string-ref i x))
|
||||
(lambda (x) (unsafe-fx+ 1 x))
|
||||
0
|
||||
(lambda (x) (unsafe-fx< x len))
|
||||
(lambda (x) #t)
|
||||
(lambda (x y) #t)))))
|
||||
(pattern (#%plain-app op:id _ s)
|
||||
#:when (id-from? #'op 'make-sequence 'racket/private/for)
|
||||
#:with s*:bytes-expr #'s
|
||||
#:with opt
|
||||
(begin (log-optimization "in-bytes" #'op)
|
||||
#'(let* ((i s*.opt)
|
||||
(len (bytes-length i)))
|
||||
(values (lambda (x) (bytes-ref i x))
|
||||
(lambda (x) (unsafe-fx+ 1 x))
|
||||
0
|
||||
(lambda (x) (unsafe-fx< x len))
|
||||
(lambda (x) #t)
|
||||
(lambda (x y) #t))))))
|
Loading…
Reference in New Issue
Block a user