2006-04-03 01:33:52 -04:00
|
|
|
! Copyright (C) 2006 Slava Pestov.
|
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
2006-04-03 02:18:56 -04:00
|
|
|
IN: compiler
|
|
|
|
USING: arrays generic inference kernel math
|
2006-04-03 01:33:52 -04:00
|
|
|
namespaces 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
|
|
|
|
2006-04-05 02:43:37 -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 ;
|
2006-04-05 02:43:37 -04:00
|
|
|
|
2006-04-03 01:33:52 -04:00
|
|
|
: 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 -- )
|
2006-04-03 01:33:52 -04:00
|
|
|
over immediate? [ %immediate ] [ %indirect ] if , ;
|
|
|
|
|
2006-04-05 02:43:37 -04:00
|
|
|
G: vreg>stack ( value loc -- ) 1 standard-combination ;
|
|
|
|
|
|
|
|
M: f vreg>stack ( value loc -- ) 2drop ;
|
|
|
|
|
|
|
|
M: value vreg>stack ( value loc -- )
|
2006-04-11 02:45:24 -04:00
|
|
|
>r value-literal r> load-literal ;
|
2006-04-05 02:43:37 -04:00
|
|
|
|
|
|
|
M: object vreg>stack ( value loc -- )
|
|
|
|
%replace , ;
|
2006-04-03 01:33:52 -04:00
|
|
|
|
2006-04-14 03:53:45 -04:00
|
|
|
M: clean vreg>stack ( value loc -- ) 2drop ;
|
|
|
|
|
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
|
|
|
|
2006-04-05 02:43:37 -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-05 02:43:37 -04:00
|
|
|
G: stack>vreg ( value vreg loc -- operand )
|
|
|
|
2 standard-combination ;
|
|
|
|
|
|
|
|
M: f stack>vreg ( value vreg loc -- operand ) 2drop ;
|
|
|
|
|
|
|
|
M: object stack>vreg ( value vreg loc -- operand )
|
|
|
|
>r <vreg> dup r> %peek , nip ;
|
|
|
|
|
|
|
|
M: value stack>vreg ( value vreg loc -- operand )
|
2006-04-08 16:46:47 -04:00
|
|
|
drop dup value eq? [
|
|
|
|
drop
|
|
|
|
] [
|
|
|
|
>r value-literal r> <vreg> [ load-literal ] keep
|
|
|
|
] if ;
|
2006-04-03 01:33:52 -04:00
|
|
|
|
|
|
|
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-03 01:33:52 -04:00
|
|
|
|
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-03 01:33:52 -04:00
|
|
|
|
2006-04-05 02:43:37 -04:00
|
|
|
: (stack>vregs) ( values template locs -- inputs )
|
|
|
|
3array flip
|
2006-04-14 03:53:45 -04:00
|
|
|
[ first3 over [ stack>vreg <clean> ] [ 3drop f ] if ] map ;
|
|
|
|
|
|
|
|
: ?clean ( obj -- obj )
|
|
|
|
dup clean? [ delegate ] when ;
|
|
|
|
|
|
|
|
: %get ( obj -- value )
|
|
|
|
get ?clean dup value? [ value-literal ] when ;
|
2006-04-03 01:33:52 -04:00
|
|
|
|
2006-04-09 23:11:19 -04:00
|
|
|
: phantom-vregs ( values template -- )
|
2006-04-14 03:53:45 -04:00
|
|
|
[ second set ] 2each ;
|
2006-04-08 03:13:01 -04:00
|
|
|
|
2006-04-11 02:45:24 -04:00
|
|
|
: stack>vregs ( values phantom template -- values )
|
2006-04-09 22:23:00 -04:00
|
|
|
[
|
|
|
|
[ first ] map alloc-regs
|
2006-04-09 23:11:19 -04:00
|
|
|
pick length rot phantom-locs
|
|
|
|
(stack>vregs)
|
2006-04-11 02:45:24 -04:00
|
|
|
] 2keep length neg swap adjust-phantom ;
|
2006-04-08 03:13:01 -04:00
|
|
|
|
2006-04-09 22:23:00 -04:00
|
|
|
: compatible-vreg? ( value vreg -- ? )
|
2006-04-08 16:46:47 -04:00
|
|
|
swap dup value? [ 2drop f ] [ vreg-n = ] if ;
|
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-08 16:46:47 -04:00
|
|
|
{ [ dup any-reg eq? ] [ drop vreg? ] }
|
2006-04-08 03:13:01 -04:00
|
|
|
{ [ dup integer? ] [ compatible-vreg? ] }
|
|
|
|
{ [ dup value eq? ] [ drop value? ] }
|
|
|
|
} 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
|
|
|
|
|
|
|
: template-input ( values template phantom -- )
|
2006-04-11 02:45:24 -04:00
|
|
|
dup vregs>stack swap [ stack>vregs ] keep phantom-vregs ;
|
2006-04-03 01:33:52 -04:00
|
|
|
|
2006-04-09 23:11:19 -04:00
|
|
|
: template-inputs ( values template values template -- )
|
2006-04-11 02:45:24 -04:00
|
|
|
pick over templates-match? [
|
|
|
|
phantom-r get optimized-input drop
|
|
|
|
phantom-d get optimized-input drop
|
|
|
|
] [
|
|
|
|
phantom-r get template-input
|
|
|
|
phantom-d get template-input
|
|
|
|
] if ;
|
|
|
|
|
|
|
|
: drop-phantom ( -- )
|
|
|
|
end-basic-block -1 phantom-d get adjust-phantom ;
|
2006-04-03 01:33:52 -04:00
|
|
|
|
2006-04-14 03:53:45 -04:00
|
|
|
: prep-output ( value -- value )
|
|
|
|
{
|
|
|
|
{ [ dup value? ] [ ] }
|
|
|
|
{ [ dup clean? ] [ delegate dup value? [ get ] unless ] }
|
|
|
|
{ [ t ] [ get ?clean ] }
|
|
|
|
} cond ;
|
|
|
|
|
2006-04-11 02:45:24 -04:00
|
|
|
: template-output ( seq stack -- )
|
|
|
|
over length over adjust-phantom
|
2006-04-14 03:53:45 -04:00
|
|
|
swap [ prep-output ] map nappend ;
|
2006-04-03 01:33:52 -04:00
|
|
|
|
|
|
|
: template-outputs ( stack stack -- )
|
2006-04-11 02:45:24 -04:00
|
|
|
phantom-r get template-output
|
|
|
|
phantom-d get template-output ;
|
2006-04-03 01:33:52 -04:00
|
|
|
|
|
|
|
: with-template ( node in out quot -- )
|
2006-04-11 02:45:24 -04:00
|
|
|
compute-free-vregs
|
2006-04-05 02:43:37 -04:00
|
|
|
swap >r >r >r dup node-in-d r> { } { } template-inputs
|
2006-04-03 03:22:33 -04:00
|
|
|
node set r> call r> { } template-outputs ; inline
|