Improve type inference for recursive functions

db4
Slava Pestov 2008-04-17 14:34:32 -05:00
parent 80ee4f8771
commit 608a1c03f4
2 changed files with 25 additions and 34 deletions

View File

@ -368,6 +368,25 @@ cell-bits 32 = [
] { * + shift mod fixnum-mod fixnum* fixnum+ fixnum- } inlined? ] { * + shift mod fixnum-mod fixnum* fixnum+ fixnum- } inlined?
] unit-test ] unit-test
: fib ( m -- n )
dup 2 < [ drop 1 ] [ dup 1 - fib swap 2 - fib + ] if ; inline
[ t ] [
[ 27.0 fib ] { < - } inlined?
] unit-test
[ t ] [
[ 27 fib ] { < - } inlined?
] unit-test
[ t ] [
[ 27 >bignum fib ] { < - } inlined?
] unit-test
[ f ] [
[ 27/2 fib ] { < - } inlined?
] unit-test
! Later ! Later
! [ t ] [ ! [ t ] [

View File

@ -10,12 +10,7 @@ classes.algebra generic.math optimizer.pattern-match
optimizer.backend optimizer.def-use optimizer.inlining optimizer.backend optimizer.def-use optimizer.inlining
generic.standard system ; generic.standard system ;
{ + bignum+ float+ fixnum+fast } { { + bignum+ float+ fixnum+ fixnum+fast } {
{ { number 0 } [ drop ] }
{ { 0 number } [ nip ] }
} define-identities
{ fixnum+ } {
{ { number 0 } [ drop ] } { { number 0 } [ drop ] }
{ { 0 number } [ nip ] } { { 0 number } [ nip ] }
} define-identities } define-identities
@ -41,7 +36,7 @@ generic.standard system ;
{ { @ @ } [ 2drop t ] } { { @ @ } [ 2drop t ] }
} define-identities } define-identities
{ * fixnum* bignum* float* } { { * fixnum* fixnum*fast bignum* float* } {
{ { number 1 } [ drop ] } { { number 1 } [ drop ] }
{ { 1 number } [ nip ] } { { 1 number } [ nip ] }
{ { number 0 } [ nip ] } { { number 0 } [ nip ] }
@ -89,7 +84,7 @@ generic.standard system ;
} define-identities } define-identities
: math-closure ( class -- newclass ) : math-closure ( class -- newclass )
{ fixnum integer rational real } { fixnum bignum integer rational float real number }
[ class< ] with find nip number or ; [ class< ] with find nip number or ;
: fits? ( interval class -- ? ) : fits? ( interval class -- ? )
@ -354,15 +349,17 @@ most-negative-fixnum most-positive-fixnum [a,b]
{ + [ fixnum+fast ] } { + [ fixnum+fast ] }
{ - [ fixnum-fast ] } { - [ fixnum-fast ] }
{ * [ fixnum*fast ] } { * [ fixnum*fast ] }
{ shift [ fixnum-shift-fast ] }
{ fixnum+ [ fixnum+fast ] } { fixnum+ [ fixnum+fast ] }
{ fixnum- [ fixnum-fast ] } { fixnum- [ fixnum-fast ] }
{ fixnum* [ fixnum*fast ] } { fixnum* [ fixnum*fast ] }
{ fixnum-shift [ fixnum-shift-fast ] }
! these are here as an optimization. if they weren't given ! these are here as an optimization. if they weren't given
! explicitly, the same would be inferred after an extra ! explicitly, the same would be inferred after an extra
! optimization step (see optimistic-inline?) ! optimization step (see optimistic-inline?)
{ 1+ [ 1 fixnum+fast ] } { 1+ [ 1 fixnum+fast ] }
{ 1- [ 1 fixnum-fast ] } { 1- [ 1 fixnum-fast ] }
{ 2/ [ -1 fixnum-shift ] } { 2/ [ -1 fixnum-shift-fast ] }
{ neg [ 0 swap fixnum-fast ] } { neg [ 0 swap fixnum-fast ] }
} [ } [
[ [
@ -447,31 +444,6 @@ most-negative-fixnum most-positive-fixnum [a,b]
] { } make 1array define-optimizers ] { } make 1array define-optimizers
] assoc-each ] assoc-each
: fixnum-shift-fast-pos? ( node -- ? )
#! Shifting 1 to the left won't overflow if the shift
#! count is small enough
dup dup node-in-d first node-literal 1 = [
dup node-in-d second node-interval
0 cell-bits tag-bits get - 2 - [a,b] interval-subset?
] [ drop f ] if ;
: fixnum-shift-fast-neg? ( node -- ? )
#! Shifting any number to the right won't overflow if the
#! shift count is small enough
dup node-in-d second node-interval
cell-bits 1- neg 0 [a,b] interval-subset? ;
: fixnum-shift-fast? ( node -- ? )
dup fixnum-shift-fast-pos?
[ drop t ] [ fixnum-shift-fast-neg? ] if ;
\ fixnum-shift {
{
[ dup fixnum-shift-fast? ]
[ [ fixnum-shift-fast ] f splice-quot ]
}
} define-optimizers
: convert-rem-to-and? ( #call -- ? ) : convert-rem-to-and? ( #call -- ? )
dup node-in-d { dup node-in-d {
{ [ 2dup first node-class integer class< not ] [ f ] } { [ 2dup first node-class integer class< not ] [ f ] }