factor/library/compiler/templates.factor

213 lines
5.3 KiB
Factor
Raw Normal View History

! Copyright (C) 2006 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
IN: compiler
2006-04-17 17:17:34 -04:00
USING: arrays generic inference io kernel math
namespaces prettyprint sequences vectors words ;
2006-04-09 23:11:19 -04:00
! A data stack location.
TUPLE: ds-loc n ;
! A call stack location.
TUPLE: cs-loc n ;
2006-04-14 03:53:45 -04:00
! A marker for values which are already stored in this location
TUPLE: clean ;
C: clean [ set-delegate ] keep ;
2006-04-09 23:11:19 -04:00
TUPLE: phantom-stack height ;
2006-04-09 22:23:00 -04:00
C: phantom-stack ( -- stack )
0 over set-phantom-stack-height
2006-04-09 23:11:19 -04:00
V{ } clone over set-delegate ;
2006-04-09 22:23:00 -04:00
GENERIC: finalize-height ( n stack -- )
GENERIC: <loc> ( n stack -- loc )
: (loc) phantom-stack-height - ;
: (finalize-height) ( stack word -- )
swap [
phantom-stack-height
dup zero? [ 2drop ] [ swap execute , ] if
0
] keep set-phantom-stack-height ; inline
TUPLE: phantom-datastack ;
C: phantom-datastack
[ >r <phantom-stack> r> set-delegate ] keep ;
M: phantom-datastack <loc> (loc) <ds-loc> ;
M: phantom-datastack finalize-height
\ %inc-d (finalize-height) ;
TUPLE: phantom-callstack ;
C: phantom-callstack
[ >r <phantom-stack> r> set-delegate ] keep ;
M: phantom-callstack <loc> (loc) <cs-loc> ;
M: phantom-callstack finalize-height
\ %inc-r (finalize-height) ;
: phantom-locs ( n phantom -- locs )
2006-04-09 23:11:19 -04:00
swap reverse-slice [ swap <loc> ] map-with ;
2006-04-09 22:23:00 -04:00
: phantom-locs* ( phantom -- locs )
2006-04-09 23:11:19 -04:00
dup length swap phantom-locs ;
2006-04-09 22:23:00 -04:00
: adjust-phantom ( n phantom -- )
[ phantom-stack-height + ] keep set-phantom-stack-height ;
2006-04-11 02:45:24 -04:00
GENERIC: cut-phantom ( n phantom -- seq )
M: phantom-stack cut-phantom ( n phantom -- seq )
[ delegate cut* swap ] keep set-delegate ;
2006-04-09 22:23:00 -04:00
SYMBOL: phantom-d
SYMBOL: phantom-r
2006-04-09 22:23:00 -04:00
: init-templates ( -- )
<phantom-datastack> phantom-d set
<phantom-callstack> phantom-r set ;
: immediate? ( obj -- ? )
#! fixnums and f have a pointerless representation, and
#! are compiled immediately. Everything else can be moved
#! by GC, and is indexed through a table.
dup fixnum? swap f eq? or ;
2006-04-11 02:45:24 -04:00
: load-literal ( obj dest -- )
over immediate? [ %immediate ] [ %indirect ] if , ;
2006-04-17 17:17:34 -04:00
: vreg>stack ( value loc -- )
{
{ [ over not ] [ 2drop ] }
{ [ over clean? ] [ 2drop ] }
{ [ t ] [ %replace , ] }
} cond ;
2006-04-14 03:53:45 -04:00
2006-04-11 02:45:24 -04:00
: vregs>stack ( phantom -- )
dup dup phantom-locs* [ vreg>stack ] 2each
0 swap set-length ;
: finalize-phantom ( phantom -- )
dup finalize-height vregs>stack ;
2006-04-08 03:13:01 -04:00
: end-basic-block ( -- )
2006-04-11 02:45:24 -04:00
phantom-d get finalize-phantom
phantom-r get finalize-phantom ;
2006-04-17 17:17:34 -04:00
: stack>vreg ( vreg loc -- operand )
over [ >r <vreg> dup r> %peek , ] [ 2drop f ] if ;
SYMBOL: any-reg
2006-04-11 02:45:24 -04:00
SYMBOL: free-vregs
: compute-free-vregs ( -- )
2006-04-14 03:53:45 -04:00
phantom-d get phantom-r get append
[ vreg? ] subset [ vreg-n ] map
vregs length reverse diff
2006-04-11 02:45:24 -04:00
>vector free-vregs set ;
: requested-vregs ( template -- n )
[ any-reg eq? ] subset length ;
2006-04-11 02:45:24 -04:00
: sufficient-vregs? ( template template -- ? )
[ requested-vregs ] 2apply + free-vregs get length <= ;
: alloc-regs ( template -- template )
free-vregs get swap [
dup any-reg eq? [ drop pop ] [ nip ] if
] map-with ;
2006-04-17 17:17:34 -04:00
: alloc-reg# ( n -- regs )
free-vregs [ cut ] change ;
2006-04-14 03:53:45 -04:00
: ?clean ( obj -- obj )
dup clean? [ delegate ] when ;
: %get ( obj -- value )
get ?clean dup value? [ value-literal ] when ;
2006-04-17 17:17:34 -04:00
: phantom-vregs ( values template -- ) [ second set ] 2each ;
2006-04-08 03:13:01 -04:00
2006-04-17 17:17:34 -04:00
: stack>vregs ( phantom template -- values )
2006-04-09 22:23:00 -04:00
[
[ first ] map alloc-regs
2006-04-17 17:17:34 -04:00
dup length rot phantom-locs
[ stack>vreg ] 2map
2006-04-11 02:45:24 -04:00
] 2keep length neg swap adjust-phantom ;
2006-04-08 03:13:01 -04:00
: compatible-values? ( value template -- ? )
2006-04-14 03:53:45 -04:00
>r ?clean r> {
2006-04-11 02:45:24 -04:00
{ [ dup not ] [ 2drop t ] }
{ [ over not ] [ 2drop f ] }
2006-04-17 17:17:34 -04:00
{ [ dup any-reg eq? ] [ 2drop t ] }
{ [ dup integer? ] [ swap vreg-n = ] }
2006-04-08 03:13:01 -04:00
} cond ;
2006-04-11 02:45:24 -04:00
: template-match? ( template phantom -- ? )
2dup [ length ] 2apply <= [
>r dup length r> tail-slice*
t [ swap first compatible-values? and ] 2reduce
2006-04-08 03:13:01 -04:00
] [
2drop f
] if ;
2006-04-11 02:45:24 -04:00
: templates-match? ( template template -- ? )
2dup sufficient-vregs? [
phantom-r get template-match?
>r phantom-d get template-match? r> and
] [
2drop f
] if ;
: optimized-input ( template phantom -- )
over length neg over adjust-phantom
over length over cut-phantom
>r dup empty? [ drop ] [ vregs>stack ] if r>
swap phantom-vregs ;
2006-04-09 22:23:00 -04:00
2006-04-17 17:17:34 -04:00
: template-input ( template phantom -- )
2006-04-11 02:45:24 -04:00
dup vregs>stack swap [ stack>vregs ] keep phantom-vregs ;
2006-04-17 17:17:34 -04:00
: template-inputs ( template template -- )
2dup templates-match? [
phantom-r get optimized-input
phantom-d get optimized-input
2006-04-11 02:45:24 -04:00
] [
phantom-r get template-input
phantom-d get template-input
] if ;
: drop-phantom ( -- )
end-basic-block -1 phantom-d get adjust-phantom ;
2006-04-14 03:53:45 -04:00
: prep-output ( value -- value )
2006-04-17 17:17:34 -04:00
dup clean? [ delegate ] [ get ?clean ] if ;
: phantom-append ( seq stack -- )
over length over adjust-phantom swap nappend ;
2006-04-14 03:53:45 -04:00
2006-04-11 02:45:24 -04:00
: template-output ( seq stack -- )
2006-04-17 17:17:34 -04:00
>r [ prep-output ] map r> phantom-append ;
: trace-outputs ( stack stack -- )
"==== Template output:" print [ . ] 2apply ;
: template-outputs ( stack stack -- )
2006-04-17 17:17:34 -04:00
! 2dup trace-outputs
2006-04-11 02:45:24 -04:00
phantom-r get template-output
phantom-d get template-output ;
2006-04-17 17:17:34 -04:00
: with-template ( in out quot -- )
compute-free-vregs swap >r
>r { } template-inputs r> call r> { } template-outputs ;
inline