Marc:
Consider the following code:
(declare (standard-bindings)(extended-bindings)(block))
(define (expt1 a b) (define (square x) (* x x)) (cond ((= b 0) 1) ((even? b) (square (expt1 a (quotient b 2)))) (else (* a (square (expt1 a (quotient b 2)))))))
(declare (inlining-limit 100000))
(define a (expt1 2 20))
(define b (expt1 2 40))
(define c (expt1 2 80))
When compiled, this gives
peano-71% gsc -c -expansion crap loading /pkgs/Gambit-C/gambcext.scm Expansion:
(define expt1 (lambda (a b) (if (if (and (##fixnum? b) #t) (##fixnum.= b 0) (= b 0)) 1 (if (even? b) (let ((x (expt1 a (or (and (##fixnum? b) (##fixnum.quotient? b 2)) (quotient b 2))))) (or (and (##fixnum? x) (and (##fixnum? x) (##fixnum.*? x x))) (* x x))) (let ((temp (let ((x (expt1 a (or (and (##fixnum? b) (##fixnum.quotient? b 2)) (quotient b 2))))) (or (and (##fixnum? x) (and (##fixnum? x) (##fixnum.*? x x))) (* x x))))) (or (and (##fixnum? a) (and (##fixnum? temp) (##fixnum.*? a temp))) (* a temp)))))))
(define a 1048576)
(define b (or (##fixnum.*? 1048576 1048576) 1099511627776))
(define c (let ((x (or (##fixnum.*? 1048576 1048576) 1099511627776))) (or (and (##fixnum? x) (and (##fixnum? x) (##fixnum.*? x x))) (* x x))))
Note how a is completely determined, b has the code it has because (##fixnum.*? 1048576 1048576) could be #t or #f depending on whether Gambit was compiled for 32-bit or 64-bit machines, etc. It seems that the expansion of *, +, etc., was done before the constant propagation and evaluation of known functions. This should be reversed, and a, b, and c should all be reduced to constants in the compile.
Brad