[gambit-list] Guile's new compiler
Bradley Lucier
lucier at math.purdue.edu
Thu Nov 5 17:21:53 EST 2015
On 11/05/2015 07:29 AM, Marc Feeley wrote:
> You haven’t given the compiler much information to help it optimize…
>
> Try:
>
> (declare (standard-bindings))
>
> (define (a x y)
> (map (lambda (c d) (+ c d)) x y))
>
> It gives better inlining than (map + x y) . I haven’t looked into the details of why, but it is the transformations in gsc/_ptree2.scm that are involved in the inlining. Perhaps you could trace the code to see where the inlining is cut short.
>
> Did you try this with Guile also to compare?
Well, the guile compiler takes this
(let ((string->chars
(lambda (s)
(define char-at
(lambda (n) (string-ref s n)))
(define len
(lambda () (string-length s)))
(let loop ((i 0))
(if (< i (len))
(cons (char-at i)
(loop (+ 1 i)))
'())))))
(string->chars "yo"))
and turns it into
(compile-file "crap.scm" #:to 'assembly)
$2 =
"/home/lucier/.cache/guile/ccache/2.0-LE-8-2.0/home/lucier/Desktop/crap.scm.go"
which is
(load-program ((:LCASE341 . 2)) 16 (load-program () 66 #f (make-eol)
(load-symbol "filename") (load-string "crap.scm") (cons) (make-int8:0)
(make-int8 8) (make-int8:0) (cons) (cons) (make-int8 4) (make-int8 11)
(make-int8 23) (cons) (cons) (make-int8 9) (make-int8 18) (make-int8 15)
(cons) (cons) (list 0 4) (make-int8 2) (make-int8 10) (make-int8:0)
(list 0 3) (list 0 1) (list 0 3) (return)) (assert-nargs-ee/locals 0)
(make-char8 121) (make-char8 111) (list 0 2) (return) (nop) (nop) (nop)
(nop) (nop) (nop))
(which is just constructing the list of characters '(#\y #\o))
Even after adding
(declare (standard-bindings)
(fixnum)
(not safe)
(inlining-limit 1000))
Gambit does
firefly:~/Desktop> gsc -c -expansion crap
Expansion:
(let ((s "yo"))
(letrec ((loop (lambda (s i)
(if ('#<procedure #2 ##fx<> i ('#<procedure #3
##string-length> s))
('#<procedure #4 ##cons>
('#<procedure #5 ##string-ref> s i)
(let ((i ('#<procedure #6 ##fx+> 1 i)))
(if ('#<procedure #2 ##fx<>
i
('#<procedure #3 ##string-length> s))
('#<procedure #4 ##cons>
('#<procedure #5 ##string-ref> s i)
(let ((i ('#<procedure #6 ##fx+> 1 i)))
(if ('#<procedure #2 ##fx<>
i
('#<procedure #3 ##string-length> s))
('#<procedure #4 ##cons>
('#<procedure #5 ##string-ref> s i)
(let ((i ('#<procedure #6 ##fx+>
1 i)))
(if ('#<procedure #2 ##fx<>
i
('#<procedure #3
##string-length> s))
('#<procedure #4 ##cons>
('#<procedure #5
##string-ref> s i)
(loop s ('#<procedure #6
##fx+> 1 i)))
'())))
'())))
'())))
'()))))
(loop s 0)))
I.e., it never pulls that argument into the closure.
More information about the Gambit-list
mailing list