100 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Factor
		
	
	
			
		
		
	
	
			100 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Factor
		
	
	
! Copyright (C) 2008 Slava Pestov.
 | 
						|
! See http://factorcode.org/license.txt for BSD license.
 | 
						|
USING: math math.partial-dispatch namespaces sequences sets
 | 
						|
accessors assocs words kernel memoize fry combinators
 | 
						|
compiler.tree
 | 
						|
compiler.tree.combinators
 | 
						|
compiler.tree.def-use
 | 
						|
compiler.tree.def-use.simplified
 | 
						|
compiler.tree.late-optimizations ;
 | 
						|
IN: compiler.tree.modular-arithmetic
 | 
						|
 | 
						|
! This is a late-stage optimization.
 | 
						|
! See the comment in compiler.tree.late-optimizations.
 | 
						|
 | 
						|
! Modular arithmetic optimization pass.
 | 
						|
!
 | 
						|
! { integer integer } declare + >fixnum
 | 
						|
!    ==>
 | 
						|
!        [ >fixnum ] bi@ fixnum+fast
 | 
						|
 | 
						|
{ + - * bitand bitor bitxor } [
 | 
						|
    [
 | 
						|
        t "modular-arithmetic" set-word-prop
 | 
						|
    ] each-integer-derived-op
 | 
						|
] each
 | 
						|
 | 
						|
{ bitand bitor bitxor bitnot }
 | 
						|
[ t "modular-arithmetic" set-word-prop ] each
 | 
						|
 | 
						|
SYMBOL: modularize-values
 | 
						|
 | 
						|
: modular-value? ( value -- ? )
 | 
						|
    modularize-values get key? ;
 | 
						|
 | 
						|
: modularize-value ( value -- ) modularize-values get conjoin ;
 | 
						|
 | 
						|
GENERIC: maybe-modularize* ( value node -- )
 | 
						|
 | 
						|
: maybe-modularize ( value -- )
 | 
						|
    actually-defined-by [ value>> ] [ node>> ] bi
 | 
						|
    over actually-used-by length 1 = [
 | 
						|
        maybe-modularize*
 | 
						|
    ] [ 2drop ] if ;
 | 
						|
 | 
						|
M: #call maybe-modularize*
 | 
						|
    dup word>> "modular-arithmetic" word-prop [
 | 
						|
        [ modularize-value ]
 | 
						|
        [ in-d>> [ maybe-modularize ] each ] bi*
 | 
						|
    ] [ 2drop ] if ;
 | 
						|
 | 
						|
M: node maybe-modularize* 2drop ;
 | 
						|
 | 
						|
GENERIC: compute-modularized-values* ( node -- )
 | 
						|
 | 
						|
M: #call compute-modularized-values*
 | 
						|
    dup word>> \ >fixnum eq?
 | 
						|
    [ in-d>> first maybe-modularize ] [ drop ] if ;
 | 
						|
 | 
						|
M: node compute-modularized-values* drop ;
 | 
						|
 | 
						|
: compute-modularized-values ( nodes -- )
 | 
						|
    [ compute-modularized-values* ] each-node ;
 | 
						|
 | 
						|
GENERIC: optimize-modular-arithmetic* ( node -- nodes )
 | 
						|
 | 
						|
: redundant->fixnum? ( #call -- ? )
 | 
						|
    in-d>> first actually-defined-by value>> modular-value? ;
 | 
						|
 | 
						|
: optimize->fixnum ( #call -- nodes )
 | 
						|
    dup redundant->fixnum? [ drop f ] when ;
 | 
						|
 | 
						|
MEMO: fixnum-coercion ( flags -- nodes )
 | 
						|
    [ [ ] [ >fixnum ] ? ] map '[ _ spread ] splice-quot ;
 | 
						|
 | 
						|
: optimize-modular-op ( #call -- nodes )
 | 
						|
    dup out-d>> first modular-value? [
 | 
						|
        [ in-d>> ] [ word>> integer-op-input-classes ] [ ] tri
 | 
						|
        [
 | 
						|
            [
 | 
						|
                [ actually-defined-by value>> modular-value? ]
 | 
						|
                [ fixnum eq? ]
 | 
						|
                bi* or
 | 
						|
            ] 2map fixnum-coercion
 | 
						|
        ] [ [ modular-variant ] change-word ] bi* suffix
 | 
						|
    ] when ;
 | 
						|
 | 
						|
M: #call optimize-modular-arithmetic*
 | 
						|
    dup word>> {
 | 
						|
        { [ dup \ >fixnum eq? ] [ drop optimize->fixnum ] }
 | 
						|
        { [ dup "modular-arithmetic" word-prop ] [ drop optimize-modular-op ] }
 | 
						|
        [ drop ]
 | 
						|
    } cond ;
 | 
						|
 | 
						|
M: node optimize-modular-arithmetic* ;
 | 
						|
 | 
						|
: optimize-modular-arithmetic ( nodes -- nodes' )
 | 
						|
    H{ } clone modularize-values set
 | 
						|
    dup compute-modularized-values
 | 
						|
    [ optimize-modular-arithmetic* ] map-nodes ;
 |