factor/library/compiler/simplifier.factor

158 lines
4.0 KiB
Factor
Raw Normal View History

2005-01-17 15:33:12 -05:00
! Copyright (C) 2004, 2005 Slava Pestov.
! See http://factor.sf.net/license.txt for BSD license.
2004-12-14 02:57:40 -05:00
IN: compiler
USING: kernel lists namespaces words inference strings
prettyprint ;
2004-12-14 02:57:40 -05:00
2005-01-17 15:33:12 -05:00
! The linear IR being simplified is stored in this variable.
SYMBOL: simplifying
2004-12-14 02:57:40 -05:00
2005-01-17 15:33:12 -05:00
: simplifiers ( linear -- list )
#! A list of quotations with stack effect
#! ( linear -- linear ? ) that can simplify the first node
#! in the linear IR.
car car "simplifiers" word-property ;
2004-12-14 02:57:40 -05:00
2005-01-17 15:33:12 -05:00
: simplify-node ( linear list -- linear ? )
dup [
uncons >r call [
r> drop t
] [
r> simplify-node
] ifte
] when ;
2004-12-14 02:57:40 -05:00
2005-01-17 15:33:12 -05:00
: simplify-1 ( linear -- linear ? )
#! Return a new linear IR.
dup [
dup simplifiers simplify-node
[ uncons simplify-1 >r cons r> ] unless*
2004-12-17 19:27:42 -05:00
] [
2005-01-17 15:33:12 -05:00
f
2004-12-17 19:27:42 -05:00
] ifte ;
2005-01-17 15:33:12 -05:00
: simplify ( linear -- linear )
#! Keep simplifying until simplify-1 returns f.
[
dup simplifying set simplify-1 [ simplify ] when
] with-scope ;
2004-12-14 02:57:40 -05:00
2005-01-17 15:33:12 -05:00
: label-called? ( label linear -- ? )
2005-01-18 21:42:29 -05:00
[ uncons pick = swap #label = not and ] some? nip ;
#label [
[
dup car cdr simplifying get label-called?
[ f ] [ cdr t ] ifte
]
] "simplifiers" set-word-property
2004-12-14 02:57:40 -05:00
2005-01-17 15:33:12 -05:00
: next-physical? ( op linear -- ? )
cdr dup [ car car = ] [ 2drop f ] ifte ;
2004-12-14 02:57:40 -05:00
2005-01-17 15:33:12 -05:00
: cancel ( linear op -- linear param ? )
#! If the following op is as given, remove it, and return
#! its param.
over next-physical? [ cdr unswons cdr t ] [ f f ] ifte ;
2004-12-14 02:57:40 -05:00
2005-01-17 15:33:12 -05:00
\ >r [ [ \ r> cancel nip ] ] "simplifiers" set-word-property
\ r> [ [ \ >r cancel nip ] ] "simplifiers" set-word-property
\ dup [ [ \ drop cancel nip ] ] "simplifiers" set-word-property
\ swap [ [ \ swap cancel nip ] ] "simplifiers" set-word-property
2005-01-18 21:42:29 -05:00
\ drop [
[
#push-immediate cancel [
#replace-immediate swons swons t
] when
] [
#push-indirect cancel [
#replace-indirect swons swons t
] when
]
] "simplifiers" set-word-property
: find-label ( label -- rest )
simplifying get [
uncons pick = swap #label = and
] some? nip ;
2005-01-17 15:33:12 -05:00
: next-logical ( linear -- linear )
dup car car "next-logical" word-property call ;
2004-12-17 19:27:42 -05:00
#label [
2005-01-17 15:33:12 -05:00
cdr next-logical
] "next-logical" set-word-property
2004-12-17 19:27:42 -05:00
#jump-label [
2005-01-17 15:33:12 -05:00
car cdr find-label cdr
] "next-logical" set-word-property
2004-12-17 19:27:42 -05:00
2005-01-17 15:33:12 -05:00
#target-label [
car cdr find-label cdr
] "next-logical" set-word-property
2004-12-14 02:57:40 -05:00
2005-01-17 15:33:12 -05:00
: next-logical? ( op linear -- ? )
next-logical dup [ car car = ] [ 2drop f ] ifte ;
2004-12-14 02:57:40 -05:00
2005-01-17 15:33:12 -05:00
: reduce ( linear op new -- linear ? )
>r over cdr next-logical? [
unswons cdr r> swons swons t
] [
r> drop f
] ifte ;
#call [
2005-01-18 21:42:29 -05:00
[ #return #jump reduce ]
2005-01-17 15:33:12 -05:00
] "simplifiers" set-word-property
2004-12-14 02:57:40 -05:00
2005-01-17 15:33:12 -05:00
#call-label [
2005-01-18 21:42:29 -05:00
[ #return #jump-label reduce ]
2005-01-17 15:33:12 -05:00
] "simplifiers" set-word-property
: double-jump ( linear op1 op2 -- linear ? )
#! A jump to a jump is just a jump. If the next logical node
#! is a jump of type op1, replace the jump at the car of the
#! list with a jump of type op2.
2005-01-17 15:33:12 -05:00
swap pick next-logical? [
over next-logical car cdr cons swap cdr cons t
] [
drop f
] ifte ;
2004-12-18 20:24:46 -05:00
2005-01-17 15:33:12 -05:00
: useless-jump ( linear -- linear ? )
#! A jump to a label immediately following is not needed.
dup car cdr find-label over cdr eq? [ cdr t ] [ f ] ifte ;
2004-12-18 20:24:46 -05:00
2005-01-17 15:33:12 -05:00
: (dead-code) ( linear -- linear ? )
#! Remove all nodes until the next #label.
2004-12-18 20:24:46 -05:00
dup [
2005-01-17 15:33:12 -05:00
dup car car #label = [
f
] [
cdr (dead-code) t or
] ifte
] [
f
] ifte ;
2004-12-18 20:24:46 -05:00
2005-01-17 15:33:12 -05:00
: dead-code ( linear -- linear ? )
uncons (dead-code) >r cons r> ;
2004-12-18 20:24:46 -05:00
2005-01-17 15:33:12 -05:00
#jump-label [
2005-01-18 21:42:29 -05:00
[ #return #return double-jump ]
[ #jump-label #jump-label double-jump ]
[ #jump #jump double-jump ]
[ useless-jump ]
[ dead-code ]
2005-01-17 15:33:12 -05:00
] "simplifiers" set-word-property
#target-label [
2005-01-18 21:42:29 -05:00
[ #jump-label #target-label double-jump ]
[ #jump #target double-jump ]
2005-01-17 15:33:12 -05:00
] "simplifiers" set-word-property
#jump [ [ dead-code ] ] "simplifiers" set-word-property
#return [ [ dead-code ] ] "simplifiers" set-word-property
#end-dispatch [ [ dead-code ] ] "simplifiers" set-word-property