add racket/performance-hint' with begin-encourage-inline'

This commit is contained in:
Matthew Flatt 2011-12-01 10:22:49 -07:00
parent 1bc2441b5a
commit 545b37ff0d
6 changed files with 61 additions and 43 deletions

View File

@ -24,7 +24,8 @@ v4 todo:
"prop.rkt" "prop.rkt"
"misc.rkt" "misc.rkt"
"generate.rkt" "generate.rkt"
racket/stxparam) racket/stxparam
racket/performance-hint)
(require (for-syntax racket/base) (require (for-syntax racket/base)
(for-syntax "helpers.rkt") (for-syntax "helpers.rkt")
(for-syntax syntax/stx) (for-syntax syntax/stx)
@ -74,14 +75,7 @@ v4 todo:
#,(call-gen #'())] #,(call-gen #'())]
[else #,(call-gen rng-checkers)])))) [else #,(call-gen rng-checkers)]))))
(define-syntax (cross-module-inline stx) (begin-encourage-inline
(syntax-case stx ()
[(_ defn)
(syntax-property #'defn
'compiler-hint:cross-module-inline
#t)]))
(cross-module-inline
(define tail-marks-match? (define tail-marks-match?
(case-lambda (case-lambda
[(m) (and m (null? m))] [(m) (and m (null? m))]

View File

@ -0,0 +1,24 @@
(module inline '#%kernel
(#%require (for-syntax '#%kernel))
(#%provide begin-encourage-inline)
;; Attach a property to encourage the bytecode compiler to inline
;; functions:
(define-syntaxes (begin-encourage-inline)
(lambda (stx)
(let-values ([(l) (syntax->list stx)])
(if l
(datum->syntax
stx
(cons
(quote-syntax begin)
(map
(lambda (form)
(syntax-property form
'compiler-hint:cross-module-inline
#t))
(cdr l)))
stx
stx)
(raise-syntax-error #f "bad syntax" stx))))))

View File

@ -5,7 +5,7 @@
(module map '#%kernel (module map '#%kernel
(#%require '#%utils ; built into mzscheme (#%require '#%utils ; built into mzscheme
"small-scheme.rkt" "define.rkt" "small-scheme.rkt" "define.rkt"
(for-syntax '#%kernel)) "../performance-hint.rkt")
(#%provide (rename map2 map) (#%provide (rename map2 map)
(rename for-each2 for-each) (rename for-each2 for-each)
@ -14,17 +14,8 @@
;; ------------------------------------------------------------------------- ;; -------------------------------------------------------------------------
;; Attach a property to encourage the bytecode compiler to inline (begin-encourage-inline
;; `map', etc.:
(define-syntax hint-inline
(lambda (stx)
(syntax-property (cadr (syntax->list stx))
'compiler-hint:cross-module-inline
#t)))
;; -------------------------------------------------------------------------
(hint-inline
(define map2 (define map2
(let ([map (let ([map
(case-lambda (case-lambda
@ -50,9 +41,8 @@
(loop (cdr l1) (cdr l2)))])) (loop (cdr l1) (cdr l2)))]))
(map f l1 l2))] (map f l1 l2))]
[(f . args) (apply map f args)])]) [(f . args) (apply map f args)])])
map))) map))
(hint-inline
(define for-each2 (define for-each2
(let ([for-each (let ([for-each
(case-lambda (case-lambda
@ -78,9 +68,8 @@
(loop (cdr l1) (cdr l2)))])) (loop (cdr l1) (cdr l2)))]))
(for-each f l1 l2))] (for-each f l1 l2))]
[(f . args) (apply for-each f args)])]) [(f . args) (apply for-each f args)])])
for-each))) for-each))
(hint-inline
(define andmap2 (define andmap2
(let ([andmap (let ([andmap
(case-lambda (case-lambda
@ -110,9 +99,8 @@
(loop (cdr l1) (cdr l2)))]))) (loop (cdr l1) (cdr l2)))])))
(andmap f l1 l2))] (andmap f l1 l2))]
[(f . args) (apply andmap f args)])]) [(f . args) (apply andmap f args)])])
andmap))) andmap))
(hint-inline
(define ormap2 (define ormap2
(let ([ormap (let ([ormap
(case-lambda (case-lambda

View File

@ -1,6 +1,8 @@
#lang scribble/doc #lang scribble/doc
@(require scribble/manual "guide-utils.rkt" @(require scribble/manual "guide-utils.rkt"
(for-label racket/flonum racket/unsafe/ops)) (for-label racket/flonum
racket/unsafe/ops
racket/performance-hint))
@title[#:tag "performance"]{Performance} @title[#:tag "performance"]{Performance}
@ -169,10 +171,8 @@ itself calls functions other than simple primitive operations. When a
module is compiled, some functions defined at the module level are module is compiled, some functions defined at the module level are
determined to be candidates for inlining into other modules; normally, determined to be candidates for inlining into other modules; normally,
only trivial functions are considered candidates for cross-module only trivial functions are considered candidates for cross-module
inlining, but a programmer can attach a inlining, but a programmer can wrap a function definition with
@indexed-racket['compiler-hint:cross-module-inline] @tech[#:doc '(lib @racket[begin-encourage-inline] to encourage inlining
"scribblings/reference/reference.scrbl")]{syntax property} (with a
true value) to a function's definition form to encourage inlining
of the function. of the function.
Primitive operations like @racket[pair?], @racket[car], and Primitive operations like @racket[pair?], @racket[car], and

View File

@ -10,7 +10,8 @@
racket/provide racket/provide
racket/package racket/package
racket/splicing racket/splicing
racket/runtime-path)) racket/runtime-path
racket/performance-hint))
@(define require-eval (make-base-eval)) @(define require-eval (make-base-eval))
@(define syntax-eval @(define syntax-eval
@ -2084,9 +2085,9 @@ z
If a @racket[define-values] form for a function definition in a module If a @racket[define-values] form for a function definition in a module
body has a @indexed-racket['compiler-hint:cross-module-inline] body has a @indexed-racket['compiler-hint:cross-module-inline]
@tech{syntax property} with a true value, then the Racket treats the @tech{syntax property} with a true value, then the Racket treats the
property as a performance hint. See property as a performance hint. See
@guidesecref["func-call-performance"] in @|Guide| for more @guidesecref["func-call-performance"] in @|Guide| for more
information.} information, and see also @racket[begin-encourage-inline].}
@defform*[[(define-syntax id expr) @defform*[[(define-syntax id expr)
@ -2591,3 +2592,14 @@ syntactic forms or languages that supply a more limited kind of
@close-eval[require-eval] @close-eval[require-eval]
@close-eval[meta-in-eval] @close-eval[meta-in-eval]
@;------------------------------------------------------------------------
@section[#:tag "performance-hint"]{Performance Hints: @racket[begin-encourage-inline]}
@note-lib-only[racket/performance-hint]
@defform[(begin-encourage-inline form ...)]{
Attaches a @racket['compiler-hint:cross-module-inline]
@tech{syntax property} to each @racket[form], which is useful when a
@racket[form] is a function definition. See @racket[define-values].}

View File

@ -1382,16 +1382,16 @@
(null? 10))) (null? 10)))
(module check-inline-request racket/base (module check-inline-request racket/base
(require racket/performance-hint)
(provide loop) (provide loop)
(define loop (begin-encourage-inline
(begin (define loop
'compiler-hint:cross-module-inline ;; large enough that the compiler wouldn't infer inlining:
;; large enough that the compiler wouldn't infer inlining: (lambda (f n)
(lambda (f n) (let loop ([i n])
(let loop ([i n]) (if (zero? i)
(if (zero? i) 10
10 (cons (f i) (loop (sub1 n)))))))))
(cons (f i) (loop (sub1 n)))))))))
(test-comp `(module m racket/base (test-comp `(module m racket/base
(require 'check-inline-request) (require 'check-inline-request)