<!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>