<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
<HTML>
<HEAD>
  <META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=UTF-8">
  <META NAME="GENERATOR" CONTENT="GtkHTML/4.1.92">
</HEAD>
<BODY>
Marc:<BR>
<BR>
Here's a simple benchmark harness plus two tests:<BR>
<BR>
<BLOCKQUOTE>
<PRE>
(declare (standard-bindings)
         (extended-bindings)
         (block))

(declare (inline))

(define (inline-unsafe-flonum-+ x y)
  (declare (not safe)
           (flonum))
  (+ x y))

(define (inline-safe-flonum-+ x y)
  (declare (flonum))
  (+ x y))

(define-macro (test fn x y)

  (define (extend-name fn)
    (string->symbol (string-append "test-" (symbol->string fn))))

  `(begin
     (define (,(extend-name fn) x y)
       (declare (not safe))
       (let outer-loop ((x x)
                        (y y)
                        (number-of-tests 2)
                        (begin-time #f)
                        (i #f))
         (##gc)
         
         (let inner-loop ((x x)
                          (y y)
                          (number-of-tests number-of-tests)
                          (begin-time (cpu-time))
                          (i 0))
           (if (fx< i number-of-tests)
               (begin
                 (let ()
                   (declare (inlining-limit 10000))
                   (,fn x y))
                 (inner-loop x
                             y
                             number-of-tests
                             begin-time
                             (fx+ i 1)))
               (let ((run-time (fl- (cpu-time) begin-time)))
                 (if (fl< 1.0 run-time)
                     (pp (list (fl/ (exact->inexact number-of-tests)
                                    run-time)
                               '(,fn x y)
                               ))
                     (outer-loop x
                                 y
                                 (fx* 2 number-of-tests)
                                 begin-time
                                 #f)))))))
     (,(extend-name fn) ,x ,y)))

(test inline-unsafe-flonum-+ 2. 3.)
(test inline-safe-flonum-+ 2. 3.)

</PRE>
</BLOCKQUOTE>
Here's the compiled output:<BR>
<BR>
<BLOCKQUOTE>
<PRE>
heine:~/programs/gambc-v4_6_2-devel> gsc -c -expansion crap-test+.scm
Expansion:

(define inline-unsafe-flonum-+ (lambda (x y) ('#<procedure #2 ##fl+> x y)))

(define inline-safe-flonum-+ (lambda (x y) (if (and ('#<procedure #3 ##flonum?> y) ('#<procedure #3 ##flonum?> x)) ('#<procedure #2 ##fl+> x y) ('#<procedure #4 fl+> x y))))

(define test-inline-unsafe-flonum-+
  (lambda (x y)
    (letrec ((outer-loop
              (lambda (x y number-of-tests begin-time i)
                (let ((begin-temp.1 (##gc)))
                  (letrec ((inner-loop
                            (lambda (x y number-of-tests begin-time i)
                              (if ('#<procedure #5 ##fx<> i number-of-tests)
                                  (let ((begin-temp.0 (let ((x x) (y y)) ('#<procedure #2 ##fl+> x y)))) (inner-loop x y number-of-tests begin-time ('#<procedure #6 ##fx+> i 1)))
                                  (let ((run-time ('#<procedure #7 ##fl-> (cpu-time) begin-time)))
                                    (if ('#<procedure #8 ##fl<> 1. run-time)
                                        (pp ('#<procedure #9 ##list>
                                             ('#<procedure #10 ##fl/>
                                              (if ('#<procedure #11 ##fixnum?> number-of-tests)
                                                  ('#<procedure #12 ##fl<-fx> number-of-tests)
                                                  (if ('#<procedure #3 ##flonum?> number-of-tests) number-of-tests ('#<procedure #13 exact->inexact> number-of-tests)))
                                              run-time)
                                             '(inline-unsafe-flonum-+ x y)))
                                        (outer-loop x y ('#<procedure #14 ##fx*> 2 number-of-tests) begin-time #f)))))))
                    (inner-loop x y number-of-tests (cpu-time) 0))))))
      (outer-loop x y 2 #f #f))))

(test-inline-unsafe-flonum-+ 2. 3.)

(define test-inline-safe-flonum-+
  (lambda (x y)
    (letrec ((outer-loop
              (lambda (x y number-of-tests begin-time i)
                (let ((begin-temp.3 (##gc)))
                  (letrec ((inner-loop
                            (lambda (x y number-of-tests begin-time i)
                              (if ('#<procedure #5 ##fx<> i number-of-tests)
                                  (let ((begin-temp.2 (let ((x x) (y y)) (if (and ('#<procedure #3 ##flonum?> y) ('#<procedure #3 ##flonum?> x)) ('#<procedure #2 ##fl+> x y) ('#<procedure #4 fl+> x y)))))
                                    (inner-loop x y number-of-tests begin-time ('#<procedure #6 ##fx+> i 1)))
                                  (let ((run-time ('#<procedure #7 ##fl-> (cpu-time) begin-time)))
                                    (if ('#<procedure #8 ##fl<> 1. run-time)
                                        (pp ('#<procedure #9 ##list>
                                             ('#<procedure #10 ##fl/>
                                              (if ('#<procedure #11 ##fixnum?> number-of-tests)
                                                  ('#<procedure #12 ##fl<-fx> number-of-tests)
                                                  (if ('#<procedure #3 ##flonum?> number-of-tests) number-of-tests ('#<procedure #13 exact->inexact> number-of-tests)))
                                              run-time)
                                             '(inline-safe-flonum-+ x y)))
                                        (outer-loop x y ('#<procedure #14 ##fx*> 2 number-of-tests) begin-time #f)))))))
                    (inner-loop x y number-of-tests (cpu-time) 0))))))
      (outer-loop x y 2 #f #f))))

(test-inline-safe-flonum-+ 2. 3.)

</PRE>
</BLOCKQUOTE>
Now see that<BR>
<BR>
<BLOCKQUOTE>
<PRE>
('#<procedure #2 ##fl+> x y))
</PRE>
</BLOCKQUOTE>
<BR>
is in the expansion of each test loop (at begin-temp.0 and begin-temp.2), but that addition is not in the C-code (presumably because it is not referenced).<BR>
<BR>
It's OK with me that the compiler removes this code; what I find troubling is that it's still in the "expansion" of the scheme code---it appears that there are optimizations done after the expansion but before code generation.<BR>
<BR>
I'd like to rely on the output of '-expansion' more and to rely on reading the C code (or the resulting assembly code in extreme cases) less in trying to figure out how gsc will compile my code.<BR>
<BR>
Can the '-expansion' be emitted later in the compilation process, after all code-visible optimizations have been made?<BR>
<BR>
Brad
</BODY>
</HTML>