factor/library/compiler/linearizer.factor

91 lines
2.6 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-09-08 22:23:54 -04:00
GENERIC: linearize* ( node -- )
: 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-09-09 23:40:08 -04:00
[
%prologue ,
linearize*
] { } make ;
2005-05-17 16:13:08 -04:00
2005-09-08 22:23:54 -04:00
: linearize-next node-successor linearize* ;
2004-12-05 23:00:52 -05:00
2005-09-08 22:23:54 -04:00
M: f linearize* ( f -- ) drop ;
2005-05-17 16:13:08 -04:00
2005-09-08 22:23:54 -04:00
M: node linearize* ( node -- ) linearize-next ;
2005-05-17 16:13:08 -04:00
2005-09-08 22:23:54 -04:00
M: #label linearize* ( node -- )
2005-09-10 01:38:17 -04:00
<label> [
%return-to ,
dup node-param %label ,
dup node-child linearize*
] keep %label ,
linearize-next ;
2005-09-10 00:55:46 -04:00
2005-09-08 22:23:54 -04:00
: ?tail-call ( node caller jumper -- next )
2005-09-10 01:38:17 -04:00
>r >r dup node-successor #return? [
2005-09-08 22:23:54 -04:00
node-param r> drop r> execute ,
] [
dup node-param r> execute , r> drop linearize-next
] ifte ; inline
2005-06-08 04:49:05 -04:00
2005-09-08 22:23:54 -04:00
: intrinsic ( #call -- quot ) node-param "intrinsic" word-prop ;
2005-06-08 04:49:05 -04:00
: ifte-intrinsic ( #call -- quot )
dup node-successor #ifte?
[ node-param "ifte-intrinsic" word-prop ] [ drop f ] ifte ;
: linearize-ifte ( node label -- )
#! Assume the quotation emits a VOP that jumps to the label
#! if some condition holds; we linearize the false branch,
#! then the label, then the true branch.
>r node-children first2 linearize* r> %label , linearize* ;
2005-09-08 22:23:54 -04:00
M: #call linearize* ( node -- )
dup ifte-intrinsic [
>r <label> 2dup r> call
>r node-successor r> linearize-ifte
2005-09-08 22:23:54 -04:00
] [
dup intrinsic [
dupd call linearize-next
] [
\ %call \ %jump ?tail-call
] ifte*
2005-09-08 22:23:54 -04:00
] ifte* ;
2005-05-06 18:33:40 -04:00
2005-09-08 22:23:54 -04:00
M: #call-label linearize* ( node -- )
\ %call-label \ %jump-label ?tail-call ;
2005-06-09 19:49:31 -04:00
2005-09-08 22:23:54 -04:00
M: #ifte linearize* ( node -- )
<label> dup in-1 -1 %inc-d , 0 %jump-t , linearize-ifte ;
: 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
2005-09-08 22:23:54 -04:00
-1 %inc-d ,
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 -- )
2005-09-08 22:23:54 -04:00
[ uncons %label , linearize* ] each ;
2004-12-13 16:28:28 -05:00
2005-09-08 22:23:54 -04:00
M: #dispatch linearize* ( vtable -- )
#! The parameter is a list of nodes, each one is a branch to
2004-12-05 21:17:09 -05:00
#! take in case the top of stack has that type.
node-children dispatch-head dispatch-body ;
2005-09-08 22:23:54 -04:00
M: #return linearize* ( node -- )
2005-09-09 23:40:08 -04:00
#! Simple label returns do not count, since simple labels do
#! not push a stack frame on the C stack.
2005-09-10 01:38:17 -04:00
drop %return , ;