factor/library/compiler/optimizer/optimizer.factor

110 lines
3.0 KiB
Factor
Raw Normal View History

2006-03-02 01:12:32 -05:00
! Copyright (C) 2004, 2006 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
2005-09-09 00:17:19 -04:00
IN: optimizer
2006-08-06 20:31:15 -04:00
USING: arrays generic hashtables inference io kernel math
2006-05-02 20:26:48 -04:00
namespaces sequences test vectors ;
2006-03-06 19:19:20 -05:00
SYMBOL: optimizer-changed
GENERIC: optimize-node* ( node -- node/t )
2005-05-21 16:05:39 -04:00
: keep-optimizing ( node -- node ? )
dup optimize-node* dup t eq?
2005-09-24 15:21:17 -04:00
[ drop f ] [ nip keep-optimizing t or ] if ;
2005-05-22 02:35:38 -04:00
2006-03-06 19:19:20 -05:00
: optimize-node ( node -- node )
[
keep-optimizing [ optimizer-changed on ] when
] map-nodes ;
: optimize ( node -- node )
dup kill-values dup infer-classes [
optimizer-changed off
optimize-node
optimizer-changed get
] with-node-iterator [ optimize ] when ;
2005-07-27 01:46:06 -04:00
: prune-if ( node quot -- successor/t )
over >r call [ r> node-successor ] [ r> drop t ] if ;
inline
2005-05-22 02:35:38 -04:00
! Generic nodes
2005-07-27 01:46:06 -04:00
M: f optimize-node* drop t ;
2005-05-21 16:05:39 -04:00
2006-03-05 19:42:14 -05:00
M: node optimize-node* ( node -- t ) drop t ;
2005-05-21 16:05:39 -04:00
! #shuffle
M: #shuffle optimize-node* ( node -- node/t )
[ node-values empty? ] prune-if ;
2006-04-17 17:17:34 -04:00
! #push
M: #push optimize-node* ( node -- node/t )
[ node-out-d empty? ] prune-if ;
2006-04-17 17:17:34 -04:00
2005-08-13 04:01:21 -04:00
! #return
M: #return optimize-node* ( node -- node/t )
node-successor [ node-successor ] [ t ] if* ;
2006-08-06 20:31:15 -04:00
! Some utilities for splicing in dataflow IR subtrees
: post-inline ( #return/#values #call/#merge -- )
[
>r node-in-d r> node-out-d 2array unify-lengths first2
] keep subst-values ;
: ?hash-union ( hash/f hash -- hash )
over [ hash-union ] [ nip ] if ;
: add-node-literals ( hash node -- )
[ node-literals ?hash-union ] keep set-node-literals ;
: add-node-classes ( hash node -- )
[ node-classes ?hash-union ] keep set-node-classes ;
: (subst-classes) ( literals classes node -- )
dup [
3dup [ add-node-classes ] keep add-node-literals
node-successor (subst-classes)
] [
3drop
] if ;
: subst-classes ( #return/#values #call/#merge -- )
>r dup node-literals swap node-classes r> (subst-classes) ;
: subst-node ( old new -- )
#! The last node of 'new' becomes 'old', then values are
#! substituted. A subsequent optimizer phase kills the
#! last node of 'new' and the first node of 'old'.
last-node 2dup swap 2dup post-inline subst-classes
set-node-successor ;
! Constant branch folding
: fold-branch ( node branch# -- node )
over drop-inputs >r
>r dup node-successor r> rot node-children nth
[ subst-node ] keep r> [ set-node-successor ] keep ;
! #if
2006-08-06 22:30:52 -04:00
: known-boolean-value? ( node value -- value ? )
2dup node-literal? [
node-literal t
2006-08-06 20:31:15 -04:00
] [
2006-08-06 22:30:52 -04:00
node-class {
{ [ dup general-t class< ] [ drop t t ] }
{ [ dup \ f class< ] [ drop f t ] }
{ [ t ] [ drop f f ] }
} cond
2006-08-06 20:31:15 -04:00
] if ;
2006-08-06 22:30:52 -04:00
M: #if optimize-node* ( node -- node/t )
dup dup node-in-d first known-boolean-value?
[ 0 1 ? fold-branch ] [ 2drop t ] if ;
2006-08-06 20:31:15 -04:00
! #dispatch
M: #dispatch optimize-node* ( node -- node/t )
2006-08-06 22:30:52 -04:00
dup dup node-in-d first 2dup node-literal? [
node-literal fold-branch
2006-08-06 20:31:15 -04:00
] [
3drop t
] if ;