2005-02-22 23:07:47 -05:00
|
|
|
! 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
|
2005-12-21 02:43:41 -05:00
|
|
|
USING: arrays compiler-backend errors generic hashtables
|
|
|
|
inference kernel lists math namespaces prettyprint sequences
|
|
|
|
strings words ;
|
2004-12-01 19:48:08 -05:00
|
|
|
|
2005-12-04 19:56:42 -05:00
|
|
|
: in-1 0 0 %peek-d , ;
|
|
|
|
: in-2 0 1 %peek-d , 1 0 %peek-d , ;
|
|
|
|
: in-3 0 2 %peek-d , 1 1 %peek-d , 2 0 %peek-d , ;
|
|
|
|
: out-1 T{ vreg f 0 } 0 %replace-d , ;
|
|
|
|
|
2005-12-21 02:43:41 -05:00
|
|
|
! A map from words to linear IR.
|
|
|
|
SYMBOL: linearized
|
|
|
|
|
|
|
|
! Renamed labels. To avoid problems with labels with the same
|
|
|
|
! name in different scopes.
|
|
|
|
SYMBOL: renamed-labels
|
|
|
|
|
|
|
|
: rename-label ( label -- label )
|
|
|
|
<label> dup rot renamed-labels get set-hash ;
|
|
|
|
|
|
|
|
: renamed-label ( label -- label )
|
|
|
|
renamed-labels get hash ;
|
|
|
|
|
2005-09-08 22:23:54 -04:00
|
|
|
GENERIC: linearize* ( node -- )
|
2004-12-01 19:48:08 -05:00
|
|
|
|
2005-12-21 02:43:41 -05:00
|
|
|
: linearize-1 ( word dataflow -- )
|
2004-12-01 19:48:08 -05:00
|
|
|
#! 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-12-21 02:43:41 -05:00
|
|
|
[ %prologue , linearize* ] { } make
|
|
|
|
swap linearized get set-hash ;
|
|
|
|
|
|
|
|
: init-linearizer ( -- )
|
|
|
|
H{ } clone linearized set
|
|
|
|
H{ } clone renamed-labels set ;
|
|
|
|
|
|
|
|
: linearize ( word dataflow -- linearized )
|
|
|
|
#! Outputs a hashtable mapping from labels to their
|
|
|
|
#! respective linear IR.
|
|
|
|
init-linearizer linearize-1 linearized get ;
|
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-12-21 02:43:41 -05:00
|
|
|
: linearize-call ( node label -- )
|
|
|
|
over node-successor #return?
|
|
|
|
[ %jump , drop ] [ %call , linearize-next ] if ;
|
|
|
|
|
|
|
|
: linearize-call-label ( node -- )
|
|
|
|
dup node-param rename-label linearize-call ;
|
|
|
|
|
2005-09-08 22:23:54 -04:00
|
|
|
M: #label linearize* ( node -- )
|
2005-11-22 21:41:41 -05:00
|
|
|
#! We remap the IR node's label to a new label object here,
|
|
|
|
#! to avoid problems with two IR #label nodes having the
|
|
|
|
#! same label in different lexical scopes.
|
2005-12-21 02:43:41 -05:00
|
|
|
dup linearize-call-label dup node-param renamed-label
|
|
|
|
swap node-child linearize-1 ;
|
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
|
|
|
|
2005-09-24 15:21:17 -04:00
|
|
|
: if-intrinsic ( #call -- quot )
|
|
|
|
dup node-successor #if?
|
|
|
|
[ node-param "if-intrinsic" word-prop ] [ drop f ] if ;
|
2005-09-09 18:00:38 -04:00
|
|
|
|
2005-09-24 15:21:17 -04:00
|
|
|
: linearize-if ( node label -- )
|
2005-09-09 18:00:38 -04:00
|
|
|
#! 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 -- )
|
2005-09-24 15:21:17 -04:00
|
|
|
dup if-intrinsic [
|
2005-09-09 18:00:38 -04:00
|
|
|
>r <label> 2dup r> call
|
2005-09-24 15:21:17 -04:00
|
|
|
>r node-successor r> linearize-if
|
2005-09-08 22:23:54 -04:00
|
|
|
] [
|
2005-09-09 18:00:38 -04:00
|
|
|
dup intrinsic [
|
|
|
|
dupd call linearize-next
|
|
|
|
] [
|
2005-12-21 02:43:41 -05:00
|
|
|
dup node-param linearize-call
|
2005-09-24 15:21:17 -04:00
|
|
|
] if*
|
|
|
|
] if* ;
|
2005-05-06 18:33:40 -04:00
|
|
|
|
2005-09-08 22:23:54 -04:00
|
|
|
M: #call-label linearize* ( node -- )
|
2005-12-21 02:43:41 -05:00
|
|
|
dup node-param renamed-label linearize-call ;
|
2005-06-09 19:49:31 -04:00
|
|
|
|
2005-09-24 15:21:17 -04:00
|
|
|
M: #if linearize* ( node -- )
|
|
|
|
<label> dup in-1 -1 %inc-d , 0 %jump-t , linearize-if ;
|
2005-08-11 19:08:22 -04:00
|
|
|
|
|
|
|
: 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.
|
2005-05-06 19:49:07 -04:00
|
|
|
in-1
|
2005-09-08 22:23:54 -04:00
|
|
|
-1 %inc-d ,
|
2005-05-06 19:49:07 -04:00
|
|
|
0 %dispatch ,
|
2005-12-10 01:02:13 -05:00
|
|
|
[ <label> dup %target-label , cons ] map ;
|
2004-12-05 21:17:09 -05:00
|
|
|
|
2005-08-11 19:08:22 -04: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.
|
2005-08-11 19:08:22 -04:00
|
|
|
node-children dispatch-head dispatch-body ;
|
2004-12-08 18:39:36 -05:00
|
|
|
|
2005-09-08 22:23:54 -04:00
|
|
|
M: #return linearize* ( node -- )
|
2005-09-10 01:38:17 -04:00
|
|
|
drop %return , ;
|