2006-03-02 01:12:32 -05:00
|
|
|
! Copyright (C) 2004, 2006 Slava Pestov.
|
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
2006-04-03 02:18:56 -04:00
|
|
|
USING: arrays generic hashtables inference
|
2006-03-07 19:53:58 -05:00
|
|
|
kernel math namespaces sequences words ;
|
2006-04-14 03:53:45 -04:00
|
|
|
IN: compiler
|
2004-12-01 19:48:08 -05:00
|
|
|
|
2006-03-07 19:53:58 -05:00
|
|
|
GENERIC: stack-reserve*
|
|
|
|
|
|
|
|
M: object stack-reserve* drop 0 ;
|
|
|
|
|
|
|
|
: stack-reserve ( node -- )
|
|
|
|
0 swap [ stack-reserve* max ] each-node ;
|
|
|
|
|
2006-03-02 01:12:32 -05:00
|
|
|
DEFER: #terminal?
|
|
|
|
|
|
|
|
PREDICATE: #merge #terminal-merge node-successor #terminal? ;
|
|
|
|
|
|
|
|
UNION: #terminal POSTPONE: f #return #values #terminal-merge ;
|
|
|
|
|
|
|
|
: tail-call? ( -- ? )
|
|
|
|
node-stack get [ node-successor ] map [ #terminal? ] all? ;
|
|
|
|
|
|
|
|
GENERIC: linearize* ( node -- next )
|
|
|
|
|
|
|
|
: linearize-child ( node -- )
|
2006-04-03 03:22:33 -04:00
|
|
|
[ node@ linearize* ] iterate-nodes end-basic-block ;
|
2005-12-04 19:56:42 -05:00
|
|
|
|
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
|
|
|
|
|
2006-02-11 02:30:18 -05:00
|
|
|
: make-linear ( word quot -- )
|
2006-03-02 01:12:32 -05:00
|
|
|
[
|
2006-04-05 02:43:37 -04:00
|
|
|
init-templates
|
2006-03-07 19:53:58 -05:00
|
|
|
swap >r { } make r> linearized get set-hash
|
2006-03-02 01:12:32 -05:00
|
|
|
] with-node-iterator ; inline
|
2006-02-11 02:30:18 -05:00
|
|
|
|
2006-03-02 01:12:32 -05:00
|
|
|
: linearize-1 ( word node -- )
|
2006-03-07 19:53:58 -05:00
|
|
|
swap [
|
2006-04-03 03:22:33 -04:00
|
|
|
dup stack-reserve %prologue , linearize-child
|
2006-03-07 19:53:58 -05:00
|
|
|
] make-linear ;
|
2005-12-21 02:43:41 -05:00
|
|
|
|
|
|
|
: 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
|
|
|
|
2006-03-02 01:12:32 -05:00
|
|
|
M: node linearize* ( node -- next ) drop iterate-next ;
|
2004-12-05 23:00:52 -05:00
|
|
|
|
2006-03-02 01:12:32 -05:00
|
|
|
: linearize-call ( label -- next )
|
2006-04-03 03:22:33 -04:00
|
|
|
end-basic-block
|
2006-04-03 01:33:52 -04:00
|
|
|
tail-call? [ %jump , f ] [ %call , iterate-next ] if ;
|
2005-05-17 16:13:08 -04:00
|
|
|
|
2006-03-02 01:12:32 -05:00
|
|
|
: rename-label ( label -- label )
|
|
|
|
<label> dup rot renamed-labels get set-hash ;
|
2005-05-17 16:13:08 -04:00
|
|
|
|
2006-03-02 01:12:32 -05:00
|
|
|
: renamed-label ( label -- label )
|
|
|
|
renamed-labels get hash ;
|
2005-12-21 02:43:41 -05:00
|
|
|
|
2006-03-02 01:12:32 -05:00
|
|
|
: linearize-call-label ( label -- next )
|
|
|
|
rename-label linearize-call ;
|
2005-12-21 02:43:41 -05:00
|
|
|
|
2006-03-02 01:12:32 -05:00
|
|
|
M: #label linearize* ( node -- next )
|
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.
|
2006-03-02 01:12:32 -05:00
|
|
|
dup node-param dup linearize-call-label >r
|
2006-04-03 01:33:52 -04:00
|
|
|
renamed-label swap node-child linearize-1 r> ;
|
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
|
|
|
|
2006-03-06 23:35:32 -05:00
|
|
|
: linearize-if ( node label -- next )
|
2006-04-03 03:22:33 -04:00
|
|
|
<label> [
|
|
|
|
>r >r node-children first2 linearize-child
|
|
|
|
r> r> %jump-label , %label , linearize-child
|
|
|
|
] keep %label , iterate-next ;
|
2005-09-09 18:00:38 -04:00
|
|
|
|
2006-03-04 02:53:22 -05:00
|
|
|
M: #call linearize* ( node -- next )
|
2005-09-24 15:21:17 -04:00
|
|
|
dup if-intrinsic [
|
2006-04-19 16:19:26 -04:00
|
|
|
>r <label> dup r> call
|
2006-03-04 02:53:22 -05:00
|
|
|
>r node-successor r> linearize-if node-successor
|
2005-09-08 22:23:54 -04:00
|
|
|
] [
|
2006-03-02 01:12:32 -05:00
|
|
|
dup intrinsic
|
2006-04-19 16:19:26 -04:00
|
|
|
[ call iterate-next ] [ node-param linearize-call ] ?if
|
2005-09-24 15:21:17 -04:00
|
|
|
] if* ;
|
2005-05-06 18:33:40 -04:00
|
|
|
|
2006-03-02 01:12:32 -05:00
|
|
|
M: #call-label linearize* ( node -- next )
|
|
|
|
node-param renamed-label linearize-call ;
|
2005-06-09 19:49:31 -04:00
|
|
|
|
2006-03-02 01:12:32 -05:00
|
|
|
M: #if linearize* ( node -- next )
|
2006-04-17 17:17:34 -04:00
|
|
|
{ { 0 "flag" } } { } [
|
|
|
|
end-basic-block
|
2006-04-19 16:19:26 -04:00
|
|
|
<label> dup "flag" get %jump-t ,
|
2006-04-17 17:17:34 -04:00
|
|
|
] with-template linearize-if ;
|
2005-08-11 19:08:22 -04:00
|
|
|
|
2006-04-01 19:50:33 -05:00
|
|
|
: dispatch-head ( node -- label/node )
|
2004-12-05 21:17:09 -05:00
|
|
|
#! Output the jump table insn and return a list of
|
|
|
|
#! label/branch pairs.
|
2006-04-17 17:17:34 -04:00
|
|
|
{ { 0 "n" } } { }
|
2006-04-19 16:19:26 -04:00
|
|
|
[ end-basic-block "n" get %dispatch , ] with-template
|
2006-04-01 19:50:33 -05:00
|
|
|
node-children [ <label> dup %target-label , 2array ] map ;
|
2004-12-05 21:17:09 -05:00
|
|
|
|
2006-03-02 01:12:32 -05:00
|
|
|
: dispatch-body ( label/node -- )
|
2006-02-28 00:26:45 -05:00
|
|
|
<label> swap [
|
2006-04-03 03:22:33 -04:00
|
|
|
first2 %label , linearize-child end-basic-block
|
|
|
|
dup %jump-label ,
|
2006-02-28 00:26:45 -05:00
|
|
|
] each %label , ;
|
2004-12-13 16:28:28 -05:00
|
|
|
|
2006-03-02 01:12:32 -05:00
|
|
|
M: #dispatch linearize* ( node -- next )
|
2005-09-08 22:23:54 -04:00
|
|
|
#! 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.
|
2006-04-01 19:50:33 -05:00
|
|
|
dispatch-head dispatch-body iterate-next ;
|
2004-12-08 18:39:36 -05:00
|
|
|
|
2006-04-03 03:22:33 -04:00
|
|
|
M: #return linearize* drop end-basic-block %return , f ;
|