factor/library/compiler/linearizer.factor

96 lines
2.7 KiB
Factor
Raw Normal View History

! Copyright (C) 2004, 2005 Slava Pestov.
! See http://factor.sf.net/license.txt for BSD license.
2005-05-09 02:34:15 -04:00
IN: compiler-frontend
USING: compiler-backend errors generic lists inference kernel
math namespaces prettyprint sequences
2005-06-09 19:49:31 -04:00
strings words ;
2005-05-17 16:13:08 -04:00
GENERIC: linearize-node* ( node -- )
2005-05-17 16:13:08 -04:00
M: f linearize-node* ( f -- ) drop ;
M: node linearize-node* ( node -- ) drop ;
2005-05-17 16:13:08 -04:00
: linearize-node ( node -- )
[
dup linearize-node* node-successor linearize-node
] when* ;
: linearize ( dataflow -- linear )
#! Transform dataflow IR into linear IR. This strips out
2005-05-17 16:13:08 -04:00
#! stack flow information, and flattens conditionals into
#! jumps and labels.
2005-08-25 15:27:38 -04:00
[ %prologue , linearize-node ] [ ] make ;
2005-05-17 16:13:08 -04:00
M: #label linearize-node* ( node -- )
2005-05-06 18:33:40 -04:00
<label> dup %return-to , >r
2005-05-17 16:13:08 -04:00
dup node-param %label ,
node-children first linearize-node
2005-05-06 18:33:40 -04:00
r> %label , ;
2004-12-05 23:00:52 -05:00
2005-05-17 16:13:08 -04:00
M: #call linearize-node* ( node -- )
dup node-param
dup "intrinsic" word-prop [ call ] [ %call , drop ] ?ifte ;
2005-05-17 16:13:08 -04:00
M: #call-label linearize-node* ( node -- )
node-param %call-label , ;
: 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 ;
2004-12-05 23:00:52 -05:00
2005-06-08 04:49:05 -04:00
GENERIC: load-value ( vreg n value -- )
2005-06-09 19:49:31 -04:00
M: object load-value ( vreg n value -- )
2005-06-08 04:49:05 -04:00
drop %peek-d , ;
2005-06-09 19:49:31 -04:00
: push-literal ( vreg value -- )
literal-value dup
2005-05-17 16:13:08 -04:00
immediate? [ %immediate ] [ %indirect ] ifte , ;
2005-05-06 18:33:40 -04:00
2005-08-07 00:00:57 -04:00
M: literal load-value ( vreg n value -- )
2005-06-09 19:49:31 -04:00
nip push-literal ;
: push-1 ( value -- ) 0 swap push-literal ;
2005-06-08 04:49:05 -04:00
2005-05-17 16:13:08 -04:00
M: #push linearize-node* ( node -- )
node-out-d dup length dup %inc-d ,
1 - swap [ push-1 0 over %replace-d , ] each drop ;
M: #drop linearize-node* ( node -- )
node-in-d length %dec-d , ;
2005-05-08 00:58:06 -04:00
: ifte-head ( label -- )
2005-05-06 18:33:40 -04:00
in-1 1 %dec-d , 0 %jump-t , ;
2005-05-17 16:13:08 -04:00
M: #ifte linearize-node* ( node -- )
node-children 2unseq
<label> dup ifte-head
swap linearize-node ( false branch )
%label , ( branch target of BRANCH-T )
linearize-node ( true branch ) ;
: dispatch-head ( vtable -- label/code )
2004-12-05 21:17:09 -05:00
#! Output the jump table insn and return a list of
#! label/branch pairs.
in-1
1 %dec-d ,
0 %untag-fixnum ,
0 %dispatch ,
2005-05-06 18:33:40 -04:00
[ <label> dup %target-label , cons ] map
%end-dispatch , ;
2004-12-05 21:17:09 -05:00
: dispatch-body ( label/param -- )
2004-12-05 21:17:09 -05:00
#! Output each branch, with a jump to the end label.
[ uncons %label , linearize-node ] each ;
2004-12-13 16:28:28 -05:00
2005-05-17 16:13:08 -04:00
M: #dispatch linearize-node* ( vtable -- )
2004-12-05 21:17:09 -05:00
#! The parameter is a list of lists, each one is a branch to
#! take in case the top of stack has that type.
node-children dispatch-head dispatch-body ;
2005-05-17 16:13:08 -04:00
M: #return linearize-node* ( node -- )
drop f %return , ;