2005-08-08 15:21:14 -04:00
|
|
|
! Copyright (C) 2005 Slava Pestov.
|
|
|
|
! See http://factor.sf.net/license.txt for BSD license.
|
2005-09-09 00:17:19 -04:00
|
|
|
IN: optimizer
|
2005-09-11 20:46:55 -04:00
|
|
|
USING: arrays errors generic hashtables inference kernel lists
|
|
|
|
math math-internals sequences words ;
|
2005-08-08 15:21:14 -04:00
|
|
|
|
|
|
|
! A system for associating dataflow optimizers with words.
|
|
|
|
|
|
|
|
: optimizer-hooks ( node -- conditions )
|
|
|
|
node-param "optimizer-hooks" word-prop ;
|
|
|
|
|
|
|
|
: optimize-hooks ( node -- node/t )
|
|
|
|
dup optimizer-hooks cond ;
|
|
|
|
|
|
|
|
: define-optimizers ( word optimizers -- )
|
2005-10-29 23:25:38 -04:00
|
|
|
{ [ t ] [ drop t ] } add "optimizer-hooks" set-word-prop ;
|
2005-08-08 15:21:14 -04:00
|
|
|
|
|
|
|
: partial-eval? ( #call -- ? )
|
2005-08-12 18:02:03 -04:00
|
|
|
dup node-param "foldable" word-prop [
|
2005-08-08 15:21:14 -04:00
|
|
|
dup node-in-d [
|
2006-01-22 16:40:18 -05:00
|
|
|
dup value?
|
2005-11-27 17:45:48 -05:00
|
|
|
[ 2drop t ] [ swap node-literals ?hash* nip ] if
|
2005-08-08 15:21:14 -04:00
|
|
|
] all-with?
|
|
|
|
] [
|
|
|
|
drop f
|
2005-09-24 15:21:17 -04:00
|
|
|
] if ;
|
2005-08-08 15:21:14 -04:00
|
|
|
|
|
|
|
: literal-in-d ( #call -- inputs )
|
|
|
|
dup node-in-d [
|
2006-01-22 16:40:18 -05:00
|
|
|
dup value?
|
|
|
|
[ nip value-literal ] [ swap node-literals ?hash ] if
|
2005-08-08 15:21:14 -04:00
|
|
|
] map-with ;
|
|
|
|
|
|
|
|
: partial-eval ( #call -- node )
|
|
|
|
dup literal-in-d over node-param
|
2005-09-20 20:18:01 -04:00
|
|
|
[ with-datastack ] catch
|
2005-09-24 15:21:17 -04:00
|
|
|
[ 3drop t ] [ inline-literals ] if ;
|
2005-08-08 15:21:14 -04:00
|
|
|
|
2005-09-03 22:28:46 -04:00
|
|
|
: flip-subst ( not -- )
|
|
|
|
#! Note: cloning the vectors, since subst-values will modify
|
|
|
|
#! them.
|
|
|
|
[ node-in-d clone ] keep
|
|
|
|
[ node-out-d clone ] keep
|
|
|
|
subst-values ;
|
|
|
|
|
2005-09-24 15:21:17 -04:00
|
|
|
: flip-branches ( not -- #if )
|
|
|
|
#! If a not is followed by an #if, flip branches and
|
2006-02-28 00:26:45 -05:00
|
|
|
#! remove the not.
|
2005-09-03 22:28:46 -04:00
|
|
|
dup flip-subst node-successor dup
|
2006-03-06 23:35:32 -05:00
|
|
|
dup node-children reverse swap set-node-children ;
|
2005-08-11 19:08:22 -04:00
|
|
|
|
2005-10-29 23:25:38 -04:00
|
|
|
\ not {
|
|
|
|
{ [ dup node-successor #if? ] [ flip-branches ] }
|
|
|
|
} define-optimizers
|
2005-08-11 19:08:22 -04:00
|
|
|
|
2005-08-14 01:17:25 -04:00
|
|
|
: disjoint-eq? ( node -- ? )
|
2005-08-14 17:33:45 -04:00
|
|
|
dup node-classes swap node-in-d
|
2005-09-23 01:22:04 -04:00
|
|
|
[ swap ?hash ] map-with
|
2005-09-24 15:21:17 -04:00
|
|
|
first2 2dup and [ classes-intersect? not ] [ 2drop f ] if ;
|
2005-08-14 01:17:25 -04:00
|
|
|
|
2005-10-29 23:25:38 -04:00
|
|
|
\ eq? {
|
|
|
|
{ [ dup disjoint-eq? ] [ [ f ] inline-literals ] }
|
|
|
|
} define-optimizers
|
2005-08-12 18:02:03 -04:00
|
|
|
|
2006-05-02 01:49:52 -04:00
|
|
|
: useless-coerce? ( node -- )
|
|
|
|
dup node-in-d first over node-classes ?hash
|
|
|
|
swap node-param "infer-effect" word-prop second first eq? ;
|
|
|
|
|
|
|
|
: call>no-op ( node -- node )
|
|
|
|
[ ] dataflow [ subst-node ] keep ;
|
|
|
|
|
|
|
|
{ >fixnum >bignum >float } [
|
|
|
|
{
|
|
|
|
{ [ dup useless-coerce? ] [ call>no-op ] }
|
|
|
|
} define-optimizers
|
|
|
|
] each
|
|
|
|
|
2005-08-12 23:54:29 -04:00
|
|
|
! Arithmetic identities
|
2005-08-12 18:02:03 -04:00
|
|
|
SYMBOL: @
|
|
|
|
|
2005-08-12 23:54:29 -04:00
|
|
|
: define-identities ( words identities -- )
|
|
|
|
swap [ swap "identities" set-word-prop ] each-with ;
|
|
|
|
|
|
|
|
: literals-match? ( values template -- ? )
|
|
|
|
[
|
2006-01-22 16:40:18 -05:00
|
|
|
over value? [ >r value-literal r> ] [ nip @ ] if =
|
2005-09-03 17:49:28 -04:00
|
|
|
] 2map [ ] all? ;
|
2005-08-12 23:54:29 -04:00
|
|
|
|
|
|
|
: values-match? ( values template -- ? )
|
2005-09-18 01:37:28 -04:00
|
|
|
[ @ = [ drop f ] unless ] 2map [ ] subset all-eq? ;
|
2005-08-12 23:54:29 -04:00
|
|
|
|
|
|
|
: apply-identity? ( values identity -- ? )
|
|
|
|
first 2dup literals-match? >r values-match? r> and ;
|
|
|
|
|
2005-08-14 01:17:25 -04:00
|
|
|
: find-identity ( node -- values identity )
|
|
|
|
dup node-in-d swap node-param "identities" word-prop
|
|
|
|
[ dupd apply-identity? ] find nip ;
|
|
|
|
|
|
|
|
: apply-identities ( node -- node/f )
|
|
|
|
dup find-identity dup [
|
|
|
|
second swap dataflow-with [ subst-node ] keep
|
|
|
|
] [
|
|
|
|
3drop f
|
2005-09-24 15:21:17 -04:00
|
|
|
] if ;
|
2005-08-12 23:54:29 -04:00
|
|
|
|
2005-10-29 23:25:38 -04:00
|
|
|
[ + fixnum+ bignum+ float+ ] {
|
|
|
|
{ { @ 0 } [ drop ] }
|
|
|
|
{ { 0 @ } [ nip ] }
|
|
|
|
} define-identities
|
|
|
|
|
|
|
|
[ - fixnum- bignum- float- ] {
|
|
|
|
{ { @ 0 } [ drop ] }
|
|
|
|
{ { @ @ } [ 2drop 0 ] }
|
|
|
|
} define-identities
|
|
|
|
|
|
|
|
[ * fixnum* bignum* float* ] {
|
|
|
|
{ { @ 1 } [ drop ] }
|
|
|
|
{ { 1 @ } [ nip ] }
|
|
|
|
{ { @ 0 } [ nip ] }
|
|
|
|
{ { 0 @ } [ drop ] }
|
|
|
|
{ { @ -1 } [ drop 0 swap - ] }
|
|
|
|
{ { -1 @ } [ nip 0 swap - ] }
|
|
|
|
} define-identities
|
|
|
|
|
|
|
|
[ / /i /f fixnum/i fixnum/f bignum/i bignum/f float/f ] {
|
|
|
|
{ { @ 1 } [ drop ] }
|
|
|
|
{ { @ -1 } [ drop 0 swap - ] }
|
|
|
|
} define-identities
|
|
|
|
|
2006-01-26 23:01:14 -05:00
|
|
|
[ fixnum-mod bignum-mod ] {
|
2005-10-29 23:25:38 -04:00
|
|
|
{ { @ 1 } [ 2drop 0 ] }
|
|
|
|
} define-identities
|
|
|
|
|
|
|
|
[ bitand fixnum-bitand bignum-bitand ] {
|
|
|
|
{ { @ -1 } [ drop ] }
|
|
|
|
{ { -1 @ } [ nip ] }
|
|
|
|
{ { @ @ } [ drop ] }
|
|
|
|
{ { @ 0 } [ nip ] }
|
|
|
|
{ { 0 @ } [ drop ] }
|
|
|
|
} define-identities
|
|
|
|
|
|
|
|
[ bitor fixnum-bitor bignum-bitor ] {
|
|
|
|
{ { @ 0 } [ drop ] }
|
|
|
|
{ { 0 @ } [ nip ] }
|
|
|
|
{ { @ @ } [ drop ] }
|
|
|
|
{ { @ -1 } [ nip ] }
|
|
|
|
{ { -1 @ } [ drop ] }
|
|
|
|
} define-identities
|
|
|
|
|
|
|
|
[ bitxor fixnum-bitxor bignum-bitxor ] {
|
|
|
|
{ { @ 0 } [ drop ] }
|
|
|
|
{ { 0 @ } [ nip ] }
|
|
|
|
{ { @ -1 } [ drop bitnot ] }
|
|
|
|
{ { -1 @ } [ nip bitnot ] }
|
|
|
|
{ { @ @ } [ 2drop 0 ] }
|
|
|
|
} define-identities
|
|
|
|
|
|
|
|
[ shift fixnum-shift bignum-shift ] {
|
|
|
|
{ { 0 @ } [ drop ] }
|
|
|
|
{ { @ 0 } [ drop ] }
|
|
|
|
} define-identities
|
|
|
|
|
|
|
|
[ < fixnum< bignum< float< ] {
|
|
|
|
{ { @ @ } [ 2drop f ] }
|
|
|
|
} define-identities
|
|
|
|
|
|
|
|
[ <= fixnum<= bignum<= float<= ] {
|
|
|
|
{ { @ @ } [ 2drop t ] }
|
|
|
|
} define-identities
|
2005-08-12 23:54:29 -04:00
|
|
|
|
2005-10-29 23:25:38 -04:00
|
|
|
[ > fixnum> bignum> float>= ] {
|
|
|
|
{ { @ @ } [ 2drop f ] }
|
|
|
|
} define-identities
|
2005-08-12 23:54:29 -04:00
|
|
|
|
2005-10-29 23:25:38 -04:00
|
|
|
[ >= fixnum>= bignum>= float>= ] {
|
|
|
|
{ { @ @ } [ 2drop t ] }
|
|
|
|
} define-identities
|
2005-08-12 23:54:29 -04:00
|
|
|
|
2005-10-29 23:25:38 -04:00
|
|
|
[ eq? number= = ] {
|
|
|
|
{ { @ @ } [ 2drop t ] }
|
|
|
|
} define-identities
|
2005-08-14 01:17:25 -04:00
|
|
|
|
2006-03-06 23:35:32 -05:00
|
|
|
M: #call optimize-node* ( node -- node/t )
|
|
|
|
{
|
|
|
|
{ [ dup partial-eval? ] [ partial-eval ] }
|
|
|
|
{ [ dup find-identity nip ] [ apply-identities ] }
|
|
|
|
{ [ dup optimizer-hooks ] [ optimize-hooks ] }
|
|
|
|
{ [ dup inlining-class ] [ inline-method ] }
|
|
|
|
{ [ dup optimize-predicate? ] [ optimize-predicate ] }
|
|
|
|
{ [ t ] [ drop t ] }
|
|
|
|
} cond ;
|